From a22e8176905eeef1d988c64a6c25bc1c2fd47be0 Mon Sep 17 00:00:00 2001 From: terwer Date: Sun, 19 Jun 2022 22:33:30 +0800 Subject: [PATCH 1/6] feat:Replace args --- .gitignore | 1 + replace_arg.sh | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 replace_arg.sh diff --git a/.gitignore b/.gitignore index d70ef39..26b2111 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,4 @@ docker-compose.prod.yml src/main/resources/static/ src/main/resources/templates/ jvue-server-log/ +application-rds.properties_bak diff --git a/replace_arg.sh b/replace_arg.sh new file mode 100644 index 0000000..975e698 --- /dev/null +++ b/replace_arg.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +replaceArg() { + filename="application-rds.properties" + search=$1 + replace=$2 + if [[ $search != "" && $replace != "" ]]; then + sed -i "_bak" "s/$search/$replace/gi" $filename + fi +} + +cd ./jvue-server/src/main/resources +pwd + +replaceArg '${MYSQL_HOST}' "localhost" +replaceArg '${MYSQL_PORT}' "3306" +replaceArg '${MYSQL_DB_NAME}' "bugucms4" +replaceArg '${MYSQL_USERNAME}' "terwer" +replaceArg '${MYSQL_PASSWORD}' "123456" + +echo "done" + + From 928139b8dc5731e7d25d1428376a4192a809c9a7 Mon Sep 17 00:00:00 2001 From: terwer Date: Sun, 19 Jun 2022 22:52:24 +0800 Subject: [PATCH 2/6] feat:fix script --- replace_arg.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/replace_arg.sh b/replace_arg.sh index 975e698..f7673b2 100644 --- a/replace_arg.sh +++ b/replace_arg.sh @@ -5,7 +5,10 @@ replaceArg() { search=$1 replace=$2 if [[ $search != "" && $replace != "" ]]; then + # mac sed -i "_bak" "s/$search/$replace/gi" $filename + # linux + # sed -i "s/$search/$replace/gi" $filename fi } From b1b5abc99d7762184e0ae067de3dc92f2aa25070 Mon Sep 17 00:00:00 2001 From: terwer Date: Mon, 20 Jun 2022 00:23:10 +0800 Subject: [PATCH 3/6] feat:fix api host --- jvue-front/nuxt.config.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/jvue-front/nuxt.config.js b/jvue-front/nuxt.config.js index 270db3f..4dd5738 100644 --- a/jvue-front/nuxt.config.js +++ b/jvue-front/nuxt.config.js @@ -61,7 +61,9 @@ module.exports = { */ axios: { // See https://github.com/nuxt-community/axios-module#options - baseURL: development ? "http://localhost/api" : "http://localhost/api" + baseURL: development + ? "http://localhost/api" + : "http://v4.terwergreen.com/api" }, /* From d6245cb5ef72759d656a460bc6a5a74d0d1764b6 Mon Sep 17 00:00:00 2001 From: terwer Date: Mon, 20 Jun 2022 00:46:26 +0800 Subject: [PATCH 4/6] feat:backup database --- jvue-mysql/backup/220618/bugucms4-220618.sql | 1196 ++++++++++++++++++ 1 file changed, 1196 insertions(+) diff --git a/jvue-mysql/backup/220618/bugucms4-220618.sql b/jvue-mysql/backup/220618/bugucms4-220618.sql index e69de29..00e67bc 100644 --- a/jvue-mysql/backup/220618/bugucms4-220618.sql +++ b/jvue-mysql/backup/220618/bugucms4-220618.sql @@ -0,0 +1,1196 @@ +/* + Navicat Premium Data Transfer + + Source Server : mysql57@aliyun-cloud + Source Server Type : MySQL + Source Server Version : 50732 + Source Host : rm-wz9w2id84p6w14i8zqo.mysql.rds.aliyuncs.com:3306 + Source Schema : bugucms4 + + Target Server Type : MySQL + Target Server Version : 50732 + File Encoding : 65001 + + Date: 20/06/2022 00:45:28 +*/ + +SET NAMES utf8mb4; +SET FOREIGN_KEY_CHECKS = 0; + +-- ---------------------------- +-- Table structure for comments +-- ---------------------------- +DROP TABLE IF EXISTS `comments`; +CREATE TABLE `comments` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `post_id` int(11) NOT NULL COMMENT '文章ID', + `p_id` int(11) DEFAULT NULL COMMENT '父评论id', + `content` text NOT NULL COMMENT '评论内容', + `name` varchar(255) DEFAULT NULL COMMENT '名称', + `email` varchar(255) DEFAULT NULL COMMENT '邮箱', + `website` varchar(255) DEFAULT NULL COMMENT '主页', + `agree` int(11) NOT NULL DEFAULT '0' COMMENT '通过原因', + `disagree` int(11) NOT NULL DEFAULT '0' COMMENT '拒绝原因', + `ip` varchar(255) DEFAULT NULL COMMENT 'ip', + `agent` varchar(255) DEFAULT NULL COMMENT '来源', + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='评论表'; + +-- ---------------------------- +-- Records of comments +-- ---------------------------- +BEGIN; +INSERT INTO `comments` VALUES (1, 1, NULL, '## 测试评论\n这是我的网址[jvue](http://www.terwergreen.com)', 'terwer', '920049380@qq.com', 'http://www.terwergreen.com', 1, 0, '0.0.0.1', '', '2019-03-15 22:20:11'); +COMMIT; + +-- ---------------------------- +-- Table structure for logs +-- ---------------------------- +DROP TABLE IF EXISTS `logs`; +CREATE TABLE `logs` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '日志表', + `action` varchar(255) DEFAULT NULL COMMENT '操作', + `data` text COMMENT '数据', + `message` varchar(255) DEFAULT NULL COMMENT '信息', + `type` varchar(255) DEFAULT NULL COMMENT '类型', + `ip` varchar(255) DEFAULT NULL COMMENT 'ip', + `user_id` int(11) DEFAULT NULL COMMENT '用户ID', + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='日志表'; + +-- ---------------------------- +-- Records of logs +-- ---------------------------- +BEGIN; +COMMIT; + +-- ---------------------------- +-- Table structure for metas +-- ---------------------------- +DROP TABLE IF EXISTS `metas`; +CREATE TABLE `metas` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `name` varchar(255) NOT NULL COMMENT '属性名', + `type` varchar(45) NOT NULL COMMENT '属性类型', + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COMMENT='属性表'; + +-- ---------------------------- +-- Records of metas +-- ---------------------------- +BEGIN; +INSERT INTO `metas` VALUES (1, 'java', 'tag'); +INSERT INTO `metas` VALUES (2, 'server', 'category'); +COMMIT; + +-- ---------------------------- +-- Table structure for middles +-- ---------------------------- +DROP TABLE IF EXISTS `middles`; +CREATE TABLE `middles` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `p_id` int(11) NOT NULL COMMENT '父级属性ID', + `m_id` int(11) NOT NULL COMMENT '属性ID', + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COMMENT='文章属性关联表'; + +-- ---------------------------- +-- Records of middles +-- ---------------------------- +BEGIN; +INSERT INTO `middles` VALUES (1, 1, 1); +INSERT INTO `middles` VALUES (2, 1, 2); +COMMIT; + +-- ---------------------------- +-- Table structure for options +-- ---------------------------- +DROP TABLE IF EXISTS `options`; +CREATE TABLE `options` ( + `option_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '配置ID', + `option_group` varchar(64) NOT NULL DEFAULT '' COMMENT '配置组', + `option_name` varchar(64) NOT NULL DEFAULT '' COMMENT '配置名', + `option_value` longtext NOT NULL COMMENT '配置值', + PRIMARY KEY (`option_id`) USING BTREE, + UNIQUE KEY `option_name` (`option_name`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8mb4 COMMENT='站点配置表'; + +-- ---------------------------- +-- Records of options +-- ---------------------------- +BEGIN; +INSERT INTO `options` VALUES (11, 'siteConfig', 'domain', 'localhost:8081'); +INSERT INTO `options` VALUES (12, 'siteConfig', 'weburl', 'http://localhost:8081'); +INSERT INTO `options` VALUES (13, 'siteConfig', 'webtheme', 'default'); +INSERT INTO `options` VALUES (14, 'siteConfig', 'webname', '远方的灯塔'); +INSERT INTO `options` VALUES (15, 'siteConfig', 'webslogen', '专注于服务端技术分享'); +INSERT INTO `options` VALUES (16, 'siteConfig', 'keywords', '软件架构、服务端开发、Java、Spring、Dubbo、Zookeeper、微服务'); +INSERT INTO `options` VALUES (17, 'siteConfig', 'description', '远方的灯塔是关注与分享互联网及服务端开发技术的个人博客,致力于Java后端开发及服务端技术、软件架构、微服务技术分享。同时也记录个人的一路点滴,所蕴含的包括前端、后端、数据库等知识,欢迎您关注我们。'); +INSERT INTO `options` VALUES (18, 'siteConfig', 'debug', 'false'); +INSERT INTO `options` VALUES (19, 'siteConfig', 'beianinfo', '粤ICP备18023717号-1'); +COMMIT; + +-- ---------------------------- +-- Table structure for posts +-- ---------------------------- +DROP TABLE IF EXISTS `posts`; +CREATE TABLE `posts` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '文章ID', + `name` varchar(255) DEFAULT NULL COMMENT '文章别名', + `title` varchar(255) NOT NULL, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间', + `content` longtext COMMENT '文章内容', + `author_id` int(11) DEFAULT NULL COMMENT '作者', + `hits` int(11) NOT NULL DEFAULT '0' COMMENT '浏览数', + `tags` varchar(255) DEFAULT NULL COMMENT '标签', + `category` varchar(255) DEFAULT NULL COMMENT '分类', + `status` varchar(32) DEFAULT NULL COMMENT '状态', + `type` varchar(32) DEFAULT NULL COMMENT '类型', + `allow_comment` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否允许评论', + `comment_count` int(11) NOT NULL DEFAULT '0' COMMENT '评论数', + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=7968 DEFAULT CHARSET=utf8 COMMENT='文章表'; + +-- ---------------------------- +-- Records of posts +-- ---------------------------- +BEGIN; +INSERT INTO `posts` VALUES (1, 'hello-world', 'Hello world', '2019-03-15 22:20:11', '2019-03-16 23:32:15', '\n欢迎使用[Jvue](https://github.com/terwer/Jvue)! 这是你的第一篇博客。快点来写点什么吧\n\n![](https://raw.githubusercontent.com/terwer/jvue/master/slogan/java.png)\n\n```java\npublic static void main(String[] args){\n System.out.println(\"Hello world\");\n}\n```\n\n> 想要了解更多详细信息,可以查看[文档](https://github.com/terwer/jvue)。', 1, 0, 'First', 'New', 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (2, 'about', 'About', '2019-03-15 22:20:11', '2019-03-16 16:47:32', '# About me\n### Hello word\n这是关于我的页面\n\n* [Github](https://github.com/terwer)\n* [知乎](https://www.zhihu.com/people/terwer)\n\n### 也可以设置别的页面\n* 比如友链页面', 1, 0, NULL, NULL, 'publish', 'page', 1, 0); +INSERT INTO `posts` VALUES (3, 'a2', 'a2', '2019-03-20 19:07:33', '2019-06-07 02:26:05', '这是第二篇文章呀 \r\n# 测试标题\r\nWhen $a \\ne 0$, there are two solutions to \\(ax^2 + bx + c = 0\\) and they are\r\n $$x = {-b \\pm \\sqrt{b^2-4ac} \\over 2a}.$$', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4, 'a3', 'a3东方红东方红不符合法国和分发给规范化广泛国符合规范化广泛和规范和改革发货风格化风格化给韩国发恢复鬼画符恢复国会法国和和规范化风格和风格化风格化给发', '2019-03-20 19:15:32', '2019-09-01 01:41:47', '的发挥反对恢复大会风格和规范的护法国会你广泛广泛吧 从v分的高分豆腐干的发挥反对恢复大会风格和规范的护法国会你广泛广泛吧 从v分的高分豆腐干地方和百度的发挥反对恢复大会风格和规范的护法国会你广泛广泛吧 从v分的高分豆腐干地方和百度的发挥反对恢复大会风格和规范的护法国会你广泛广泛吧 从v分的高分豆腐干地方和百度的发挥反对恢复大会风格和规范的护法国会你广泛广泛吧 从v分的高分豆腐干地方和百度的发挥反对恢复大会风格和规范的护法国会你广泛广泛吧 从v分的高分豆腐干地方和百度的发挥反对恢复大会风格和规范的护法国会你广泛广泛吧 从v分的高分豆腐干地方和百度的发挥反对恢复大会风格和规范的护法国会你广泛广泛吧 从v分的高分豆腐干地方和百度的发挥反对恢复大会风格和规范的护法国会你广泛广泛吧 从v分的高分豆腐干地方和百度的发挥反对恢复大会风格和规范的护法国会你广泛广泛吧 从v分的高分豆腐干地方和百度的发挥反对恢复大会风格和规范的护法国会你广泛广泛吧 从v分的高分豆腐干地方和百度的发挥反对恢复大会风格和规范的护法国会你广泛广泛吧 从v分的高分豆腐干地方和百度的发挥反对恢复大会风格和规范的护法国会你广泛广泛吧 从v分的高分豆腐干地方和百度的发挥反对恢复大会风格和规范的护法国会你广泛广泛吧 从v分的高分豆腐干地方和百度的发挥反对恢复大会风格和规范的护法国会你广泛广泛吧 从v分的高分豆腐干地方和百度的发挥反对恢复大会风格和规范的护法国会你广泛广泛吧 从v分的高分豆腐干地方和百度的发挥反对恢复大会风格和规范的护法国会你广泛广泛吧 从v分的高分豆腐干地方和百度的发挥反对恢复大会风格和规范的护法国会你广泛广泛吧 从v分的高分豆腐干地方和百度的发挥反对恢复大会风格和规范的护法国会你广泛广泛吧 从v分的高分豆腐干地方和百度的发挥反对恢复大会风格和规范的护法国会你广泛广泛吧 从v分的高分豆腐干地方和百度的发挥反对恢复大会风格和规范的护法国会你广泛广泛吧 从v分的高分豆腐干地方和百度的发挥反对恢复大会风格和规范的护法国会你广泛广泛吧 从v分的高分豆腐干地方和百度的发挥反对恢复大会风格和规范的护法国会你广泛广泛吧 从v分的高分豆腐干地方和百度的发挥反对恢复大会风格和规范的护法国会你广泛广泛吧 从v分的高分豆腐干地方和百度的发挥反对恢复大会风格和规范的护法国会你广泛广泛吧 从v分的高分豆腐干地方和百度的发挥反对恢复大会风格和规范的护法国会你广泛广泛吧 从v分的高分豆腐干地方和百度的发挥反对恢复大会风格和规范的护法国会你广泛广泛吧 从v分的高分豆腐干地方和百度地方和百度', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6, 'vue-ssr-j2v8-1', 'Vue SSR配合Java的Javascript引擎j2v8实现服务端渲染1概述', '2019-03-23 23:47:26', '2019-08-31 22:21:11', '# 原文地址\r\n\r\n[http://www.terwergreen.com/post/vue-ssr-j2v8-1.html](http://www.terwergreen.com/post/vue-ssr-j2v8-1.html)\r\n\r\n# 初步实现方案探索(Node环境)\r\n\r\n```\r\n// 第 1 步:创建一个 Vue 实例\r\nconst Vue = require(\'vue\')\r\nconst app = new Vue({\r\n template: `
Hello World
`\r\n})\r\n\r\n// 第 2 步:创建一个 renderer\r\nconst renderer = require(\'vue-server-renderer\').createRenderer()\r\n\r\n// 第 3 步:将 Vue 实例渲染为 HTML\r\nrenderer.renderToString(app, (err, html) => {\r\n if (err) throw err\r\n console.log(html)\r\n // =>
Hello World
\r\n})\r\n```\r\n\r\n引入``vue-server-renderer``,他里面有一个``createRenderer``的方法,这个方法里的``renderToString``,可以把app渲染成字符串,第一个参数是vue实例,第二个参数是回调(错误参数(err),编译好的字符串(html))。\r\n\r\n# 非node环境实现服务端渲染(例如j2v8)\r\n\r\n```\r\n// entry-server.js\r\nimport Vue from \"vue\";\r\nconst renderVueComponentToString = require(\"vue-server-renderer/basic.js\");\r\n\r\nconsole.log(\"renderVueComponentToString\");\r\nconsole.log(renderVueComponentToString);\r\n\r\n// app.js\r\nconst vm = new Vue({\r\n template: `
{{ msg }}
`,\r\n data: {\r\n msg: \"hello\"\r\n }\r\n});\r\nconsole.log(\"data.msg:\" + vm.$data.msg);\r\n\r\nconsole.log(\"renderVueComponentToString\");\r\nconsole.log(renderVueComponentToString);\r\n\r\nglobal.renderServer = context => {\r\n console.log(\"context:\" + JSON.stringify(context));\r\n return new Promise((resolve, reject) => {\r\n renderVueComponentToString(vm, context, (err, res) => {\r\n if (err) {\r\n console.log(err);\r\n reject(err);\r\n }\r\n resolve(res);\r\n console.log(res);\r\n });\r\n });\r\n};\r\n```\r\n\r\n```\r\n// test-entry-server.js\r\nrequire(\"../../src/ssr/entry-server\")\r\n\r\nconst context = {\r\n url: \"/\"\r\n};\r\n\r\nconst promise = global.renderServer(context);\r\nconsole.log(\"promise\");\r\nconsole.log(promise);\r\n\r\npromise.then(\r\n value => {\r\n console.log(value);\r\n },\r\n reason => {\r\n console.log(reason);\r\n }\r\n);\r\n\r\n```\r\n\r\n## 运行结果\r\n\r\n```\r\n➜ webapp git:(develop) ✗ yarn babel-node ./tests/ssr/test-entry-server.js --presets=@babel/preset-env\r\nyarn run v1.13.0\r\n$ /mnt/c/Users/Terwer/IdeaProjects/jvue-cli/src/main/webapp/node_modules/.bin/babel-node ./tests/ssr/test-entry-server.js --presets=@babel/preset-env\r\nrenderVueComponentToString\r\n[Function: renderToString]\r\ndata.msg:hello\r\nrenderVueComponentToString\r\n[Function: renderToString]\r\ncontext:{\"url\":\"/\"}\r\n
hello
\r\npromise\r\nPromise { \'
hello
\' }\r\n
hello
\r\nDone in 3.63s.\r\n```\r\n\r\n# Github\r\n\r\n[https://github.com/terwer/jvue](https://github.com/terwer/jvue)\r\n\r\n[https://github.com/terwer/jvue-cli](https://github.com/terwer/jvue-cli)', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7, '', '风格和规范回复', '2019-03-25 06:09:48', '2019-12-02 21:56:23', '风格化风格化', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (8, '', '风格恢复鬼画符', '2019-03-25 06:10:01', '2019-06-02 13:18:56', '风格和规范回复和 ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (9, '', '反对恢复回复给就恢复骨结核骨结核', '2019-03-25 06:12:48', '2019-12-01 12:33:31', '房管局换个房间 `风格化法国`\r\n\r\n\r\n\r\n```\r\npublic\r\n```', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (10, '', '发红包风格化风格化法国h', '2019-03-25 06:14:39', '2019-11-30 17:09:50', '风格化规范化规范化 官方', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (11, '', '发给你急忙赶回很感激很感激是德国v的附属国豆腐干梵蒂冈地方官地方梵蒂冈梵蒂冈', '2019-03-25 06:19:57', '2019-11-29 06:59:07', '工行建行给计划的非官方222`的非官方`\r\n\r\n\r\n111\r\n\r\n\r\n222\r\n\r\n```\r\ndfdf\r\n```', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (12, '', 'Vue SSR 配合Java的Javascript引擎j2v8实现服务端渲染2创建Vue2+webpack4项目', '2019-03-25 06:35:36', '2019-12-02 18:26:06', '# 前提\r\n安装好nodejs并配置好环境变量,最好是 node10,https://nodejs.org/en/download/\r\n\r\n参考我之前的文章\r\n\r\n[debian安装nodejs](https://www.cnblogs.com/tangyouwei/p/10115548.html)\r\n\r\n[Yarn && npm设置镜像源](https://www.cnblogs.com/tangyouwei/p/10313723.html)\r\n\r\n# 开始\r\n\r\n## 初始化项目\r\n\r\n首先创建一个文件夹webapp,并使用``yarn``初始化\r\n\r\n```\r\nyarn init\r\n```\r\n\r\n完整命令\r\n\r\n```zsh\r\n➜ main git:(j2v8-version) ✗ mkdir webapp\r\n➜ main git:(j2v8-version) ✗ cd webapp\r\n➜ webapp git:(j2v8-version) ✗ pwd\r\n/mnt/c/Users/Terwer/IdeaProjects/jvue/src/main/webapp\r\n➜ webapp git:(j2v8-version) ✗ yarn init\r\nyarn init v1.13.0\r\nquestion name (webapp): jvue\r\nquestion version (1.0.0):\r\nquestion description: Next light-weight,responsive project With Vue,webpack,Spring Boot and eclipse j2v8 Script engine for server-side-rendering\r\nquestion entry point (index.js): server.js\r\nquestion repository url:\r\nquestion author: Terwer\r\nquestion license (MIT):\r\nquestion private:\r\nsuccess Saved package.json\r\nDone in 317.09s.\r\n➜ webapp git:(j2v8-version) ✗\r\n```\r\n\r\n## 初始化类库\r\n\r\n```\r\n➜ webapp git:(j2v8-version) ✗ yarn\r\nyarn install v1.13.0\r\ninfo No lockfile found.\r\n[1/4] Resolving packages...\r\n[2/4] Fetching packages...\r\n[3/4] Linking dependencies...\r\n[4/4] Building fresh packages...\r\n\r\nsuccess Saved lockfile.\r\n```\r\n\r\n## 安装项目依赖\r\n\r\n```\r\nyarn add vue vue-router\r\n```\r\n\r\n## 安装webpack打包\r\n\r\n```\r\nyarn add -D webpack webpack-cli\r\n```\r\n\r\n# 项目结构\r\n\r\n所有源码放在``src``子文件下\r\n\r\n``app.js`` : 项目入口\r\n\r\n```\r\nimport Vue from \"vue\";\r\nimport App from \"./App.vue\";\r\nnew Vue({\r\n el: \"#app\",\r\n render: h => h(App)\r\n});\r\n```\r\n\r\n``App.vue``: 根组件\r\n\r\n```\r\n\r\n```\r\n\r\n``pages``: 页面,每个文件对应一个路由\r\n\r\n``components``: 子组件\r\n\r\n``router``: 路由配置\r\n\r\n``store``: vuex配置(稍后添加)\r\n\r\n``config``: 项目配置\r\n\r\n# eslint美化代码\r\n\r\n```\r\nyarn add -D eslint babel-eslint eslint-config-google eslint-loader eslint-plugin-html eslint-plugin-vue @vue/eslint-config-prettier\r\n```\r\n\r\n``.eslintrc.js``\r\n\r\n```\r\nconst config = require(\"./config\");\r\n\r\nmodule.exports = {\r\n root: true,\r\n env: {\r\n node: true\r\n },\r\n extends: [\r\n \"google\",\r\n \"eslint:recommended\",\r\n \"plugin:vue/essential\",\r\n \"@vue/prettier\"\r\n ],\r\n // required to lint *.vue files\r\n plugins: [\"html\"],\r\n settings: {\r\n \"import/resolver\": {\r\n webpack: {\r\n config: \"build/webpack.base.conf.js\"\r\n }\r\n }\r\n },\r\n // add your custom rules here\r\n rules: {\r\n \"no-console\": \"off\",\r\n\r\n // allow debugger; instruction during development\r\n \"no-debugger\": config.isProduction ? 2 : 0,\r\n\r\n \"no-unused-vars\": [\r\n 2,\r\n {\r\n vars: \"local\",\r\n args: \"none\"\r\n }\r\n ],\r\n semi: [\"error\", \"always\"],\r\n\r\n // don\"t require comma in the last line of an object/dictionary declaration\r\n \"comma-dangle\": [\"error\", \"never\"],\r\n\r\n // force space after and before curly braces in object/dict declarations\r\n \"object-curly-spacing\": [\"error\", \"always\"],\r\n\r\n // ignore max-len for comments\r\n \"max-len\": [\r\n \"error\",\r\n {\r\n code: 100,\r\n ignoreComments: true,\r\n ignoreTrailingComments: true,\r\n ignoreUrls: true,\r\n ignoreStrings: true\r\n }\r\n ],\r\n\r\n // force \"===\" in comparisons when ambiguous\r\n eqeqeq: [\"error\", \"smart\"],\r\n\r\n // force double quotes\r\n quotes: [\"error\", \"double\"],\r\n\r\n \"require-jsdoc\": 1,\r\n\r\n \"new-cap\": [\"error\", { capIsNew: false }]\r\n },\r\n parserOptions: {\r\n sourceType: \"module\",\r\n parser: \"babel-eslint\"\r\n }\r\n};\r\n```\r\n\r\n``package.json`` 添加命令\r\n\r\n```\r\n \"lint\": \"eslint --ext .js,.vue,.html --ignore-path .gitignore --ignore-pattern !.eslintrc.js --ignore-pattern !.babelrc.js . --fix --color\",\r\n```\r\n\r\n# webpack项目打包配置\r\n\r\n安装 ``vue-loader``\r\n\r\n```\r\nyarn add -D vue-loader vue-template-compiler vue-style-loader css-loader\r\n```\r\n\r\n首先配置非服务端渲染\r\n\r\n安装 ``webpack-dev-server`` 以及 ``html-webpack-plugin``\r\n\r\n```\r\nyarn add -D webpack-dev-server html-webpack-plugin\r\n```\r\n\r\n\r\n``webpack.nossr.config.js``\r\n\r\n```\r\nconst { VueLoaderPlugin } = require(\"vue-loader\");\r\nconst HtmlWebpackPlugin = require(\"html-webpack-plugin\");\r\nmodule.exports = {\r\n mode: \"development\",\r\n node: {\r\n fs: \"empty\",\r\n module: \"empty\"\r\n },\r\n entry: \"./src/app.js\",\r\n module: {\r\n rules: [\r\n {\r\n test: /\\.vue$/,\r\n use: \"vue-loader\"\r\n }\r\n ]\r\n },\r\n plugins: [\r\n new VueLoaderPlugin(),\r\n new HtmlWebpackPlugin({\r\n template: \"./public/index.ejs\",\r\n title: \"Next Vue SSR Project for Java j2v8 Script engine\",\r\n favicon: \"./public/favicon.ico\",\r\n inject: true\r\n })\r\n ],\r\n devServer: {\r\n host: \"0.0.0.0\",\r\n port: 8888\r\n }\r\n};\r\n```\r\n\r\n``package.json`` 添加命令\r\n\r\n```\r\n \"nossr\": \"webpack-dev-server --config build/webpack.nossr.config.js --progress\"\r\n```\r\n\r\n# 查看结果\r\n\r\n运行 ``yarn nossr`` ,查看结果', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (13, '', '2018-03-25 知识点做题相关接口文档', '2019-03-25 06:59:39', '2019-05-28 13:05:34', '# 根据课程获取知识点列表\r\n/knowledge/list\r\n\r\ntokenString\r\nJ09qu_qhFNMAIN6bKa7qVPhDY5RDNrCDONUVP4kPIdCFCLL6KXnb2WtCeMD2_M_Ad3JT4uKTwvQtoS5HgQQiXOsjKUP-1GTXVOuIZCUQqyc\r\n(对应personId:64927)\r\n\r\nlessonId\r\n2756327\r\n\r\n2755355(做过题目的)\r\n\r\n# 根据知识点获取考点下面的题目(每个考点取3道题目)\r\n/knowledge/relateQuestion\r\n\r\n## 未做过题目的\r\noutState\r\n0\r\n\r\nqknowledgeId\r\n88\r\n\r\ntokenString\r\nJ09qu_qhFNMAIN6bKa7qVPhDY5RDNrCDONUVP4kPIdCFCLL6KXnb2WtCeMD2_M_Ad3JT4uKTwvQtoS5HgQQiXOsjKUP-1GTXVOuIZCUQqyc\r\n\r\nversion // 版本号,必传,知识点列表接口带出来的,不用加1\r\n0\r\n\r\n## 做过题目的\r\noutState\r\n1\r\n\r\nqknowledgeId\r\n83\r\n\r\ntokenString\r\nJ09qu_qhFNMAIN6bKa7qVPhDY5RDNrCDONUVP4kPIdCFCLL6KXnb2WtCeMD2_M_Ad3JT4uKTwvQtoS5HgQQiXOsjKUP-1GTXVOuIZCUQqyc\r\n\r\nversion\r\n1\r\n\r\n# 提交题目\r\n/question/submitAnswer\r\n\r\ntokenString\r\nJ09qu_qhFNMAIN6bKa7qVPhDY5RDNrCDONUVP4kPIdCFCLL6KXnb2WtCeMD2_M_Ad3JT4uKTwvQtoS5HgQQiXOsjKUP-1GTXVOuIZCUQqyc\r\n\r\n```\r\n{\r\n \"isFinish\": 0,\r\n \"listResultRecord\": [\r\n {\r\n \"isTrue\": 0,\r\n \"personId\": 0,\r\n \"qbankId\": 0,\r\n \"qbankParentid\": 0,\r\n \"questionResult\": \"string\",\r\n \"sort\": 0,\r\n \"version\": 0 //版本号,必传, 知识点列表接口带出来的,需要加1。一次做题过程中所有的题目仅仅只加一次\r\n }\r\n ]\r\n}\r\n```\r\n\r\n# 查看解析\r\n/question/explain\r\ntokenString\r\nJ09qu_qhFNMAIN6bKa7qVPhDY5RDNrCDONUVP4kPIdCFCLL6KXnb2WtCeMD2_M_Ad3JT4uKTwvQtoS5HgQQiXOsjKUP-1GTXVOuIZCUQqyc\r\n\r\nisTrue // 可选,对错,-1 全部/1 正确/0 错\r\n\r\npageNumber // 可选,页码,默认1\r\n\r\npageSize // 可选,每页展示的数目,默认10\r\n\r\nversion // 版本号,必传,知识点列表接口带出来的,不用加1\r\n1\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n# 根据课程获取知识点列表\r\n/knowledge/list\r\n\r\ntokenString\r\nJ09qu_qhFNMAIN6bKa7qVPhDY5RDNrCDONUVP4kPIdCFCLL6KXnb2WtCeMD2_M_Ad3JT4uKTwvQtoS5HgQQiXOsjKUP-1GTXVOuIZCUQqyc\r\n(对应personId:64927)\r\n\r\nlessonId\r\n2756327\r\n\r\n2755355(做过题目的)\r\n\r\n# 根据知识点获取考点下面的题目(每个考点取3道题目)\r\n/knowledge/relateQuestion\r\n\r\n## 未做过题目的\r\noutState\r\n0\r\n\r\nqknowledgeId\r\n88\r\n\r\ntokenString\r\nJ09qu_qhFNMAIN6bKa7qVPhDY5RDNrCDONUVP4kPIdCFCLL6KXnb2WtCeMD2_M_Ad3JT4uKTwvQtoS5HgQQiXOsjKUP-1GTXVOuIZCUQqyc\r\n\r\nversion // 版本号,必传,知识点列表接口带出来的,不用加1\r\n0\r\n\r\n## 做过题目的\r\noutState\r\n1\r\n\r\nqknowledgeId\r\n83\r\n\r\ntokenString\r\nJ09qu_qhFNMAIN6bKa7qVPhDY5RDNrCDONUVP4kPIdCFCLL6KXnb2WtCeMD2_M_Ad3JT4uKTwvQtoS5HgQQiXOsjKUP-1GTXVOuIZCUQqyc\r\n\r\nversion\r\n1\r\n\r\n# 提交题目\r\n/question/submitAnswer\r\n\r\ntokenString\r\nJ09qu_qhFNMAIN6bKa7qVPhDY5RDNrCDONUVP4kPIdCFCLL6KXnb2WtCeMD2_M_Ad3JT4uKTwvQtoS5HgQQiXOsjKUP-1GTXVOuIZCUQqyc\r\n\r\n```\r\n{\r\n \"isFinish\": 0,\r\n \"listResultRecord\": [\r\n {\r\n \"isTrue\": 0,\r\n \"personId\": 0,\r\n \"qbankId\": 0,\r\n \"qbankParentid\": 0,\r\n \"questionResult\": \"string\",\r\n \"sort\": 0,\r\n \"version\": 0 //版本号,必传, 知识点列表接口带出来的,需要加1。一次做题过程中所有的题目仅仅只加一次\r\n }\r\n ]\r\n}\r\n```\r\n\r\n# 查看解析\r\n/question/explain\r\ntokenString\r\nJ09qu_qhFNMAIN6bKa7qVPhDY5RDNrCDONUVP4kPIdCFCLL6KXnb2WtCeMD2_M_Ad3JT4uKTwvQtoS5HgQQiXOsjKUP-1GTXVOuIZCUQqyc\r\n\r\nisTrue // 可选,对错,-1 全部/1 正确/0 错\r\n\r\npageNumber // 可选,页码,默认1\r\n\r\npageSize // 可选,每页展示的数目,默认10\r\n\r\nversion // 版本号,必传,知识点列表接口带出来的,不用加1\r\n1\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (1992, 'rssblog', 'RSS订阅', '2013-10-19 13:40:14', '2019-03-25 21:29:22', '

欢迎订阅我的博客:

\r\n

途径一:自定义订阅:http://feed.xinvalue.com/

\r\n

途径二:专属订阅

\r\n

\"填写您的邮件地址,订阅我们的精彩内容:\"        \"鲜果阅读器订阅图标\"

\r\n
\r\n

\"Creative本博客基于署名-非商业性使用 3.0许可协议发布,欢迎转载,演绎,但是必须保留本博客的署名terwer(包含链接http://www.xinvalue.com),且不得用于商业目的。如您有任何疑问或者授权方面的协商,请与我联系

\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2532, 'mfc-single', 'VS2010/MFC编程入门之利用MFC向导生成单文档应用程序框架', '2014-02-03 06:00:00', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

1.点菜单栏 文件->新建->项目,弹出新建项目对话框,我们可以选择工程类型。如果安装完VS2010以后第一启动时已经设置为VC++,则已安装模板->Visual C++项会默认展开,而如果没有设置VC++,则可以展开到已安装模板->其他语言->Visual C++项。因为我们要生成的是MFC程序,所以在“Visual C++”下选择“MFC”,对话框中间区域会出现三个选项:MFC ActiveX 控件MFC DLLMFC 应用程序

MFC ActiveX 控件用来生成MFC ActiveX控件程序。MFC 应用程序用来生成MFC应用程序。MFC DLL用来生成MFC动态链接库程序。当然我们要选择MFC 应用程序。
      在对话框下部有名称位置解决方案名称三个设置项。意义如下:名称--工程名,位置--解决方案路径,解决方案名称--解决方案名称。这里名称我们设为“MFCHello”,位置设置为“d:我的文档visual studio 2010Projects”的路径,解决方案名称默认和名称一样,当然可以修改为其他名字,这里我们不作修改,也使用“HelloWorld”。点“确定”按钮。

2.这时会弹出“MFC 应用程序向导”对话框,上部写有“欢迎使用MFC 应用程序向导”,下面显示了当前工程的默认设置。  

\"\"

      第一条“选项卡多文档界面(MDI)”是说此工程是多文档应用程序。如果这时直接点下面的“Finish”按钮,可生成具有上面列出设置的多文档程序。但我们此例是要建立单文档应用程序,所以点“下一步”按钮再继续设置吧。

\"\"

3.接下来弹出的对话框上部写有“应用程序类型”,当然是让选择应用程序类型,我们看到有四种类型:单个文档(单文档)、多个文档(多文档)、基于对话框(基于对话框)和多个顶级文档。我们选择单个文档类型,以生成一个单文档应用程序框架。单文档应用程序运行时是一个单窗口界面。

\"\"

      此对话框的“资源语言”还提供语言的选择,这里默认选择中文(中国)。“项目类型”可选择工程风格,我们选择默认的“Visual Studio”风格。“MFC的使用”有两个选项:在共享 DLL 中使用 MFC(动态链接库方式使用MFC)和在静态库中使用 MFC(静态库方式使用MFC)。选择在共享 DLL 中使用 MFC时MFC的类会以动态链接库的方式访问,所以我们的应用程序本身就会小些,但是发布应用程序时必须同时添加必要的动态链接库,以便在没有安装VS2010的机子上能够正常运行程序。选择在静态库中使用 MFC时MFC的类会编译到可执行文件中,所以应用程序的可执行文件要比上种方式大,但可以单独发布,不需另加包含MFC类的库。这里我们使用默认的在共享 DLL 中使用 MFC。点“下一步”按钮。

4.此时弹出上部写有“复合文档支持”的对话框,可以通过它向应用程序加入OLE支持,指定OLE选项的复合文档类型。本例不需要OLE特性,使用默认值“”。点“下一步”按钮。

\"\"

5.弹出的新对话框上部写有“文档模板属性”。“文件扩展名”可以设置程序能处理的文件的扩展名。对话框其他选项还可以更改程序窗口的标题。我们都使用默认设置,点“下一步”按钮。

\"\"

6.此时弹出的对话框主题是“数据库支持”。用于设置数据库选项。此向导可以生成数据库应用程序需要的代码。它有四个选项:

:忽略所有的数据库支持;

仅头文件:只包含定义了数据库类的头文件,但不生成对应特定表的数据库类或视图类;

不提供文件支持的数据库视图:创建对应指定表的一个数据库类和一个视图类,不附加标准文件支持;

提供文件支持的数据库视图:创建对应指定表的一个数据库类和一个视图类,并附加标准文件支持。

本例选择默认值“”,不使用数据库特性。点“下一步”按钮。

\"\"

7.这时弹出的对话框是关于“用户界面功能”,即用户界面特性。我们可以设置有无最大化按钮、最小化按钮、系统菜单和初始状态栏等。还可以选择使用菜单栏和工具栏生成简单的应用程序还是使用功能区。这里我们都选择默认设置。点“下一步”进入下一步。

\"\"

8.此时弹出“高级特性”对话框。可以设置的高级特性包括有无打印和打印预览等。在“最近文件列表上的文件数”项可以设置在程序界面的文件菜单下面最近打开文件的个数。我们仍使用默认值。点“下一步”按钮。

\"\"

9.弹出“生成类的” 对话框。在对话框上部的“生成的类”列表框内,列出了将要生成的4 个类:一个视图类(CHelloWorldView)、一个应用类(CHelloWorldApp)、一个文档类(CHelloWorldDoc)和一个主框架窗口类(CMainFrame)。在对话框下面的几个编辑框中,可以修改默认的类名、类的头文件名和源文件名。

      对于视图类,还可以修改其基类名称,默认的基类是CView,还有其他几个基类可以选择。这里我们还是使用默认设置。点“完成”按钮。 应用程序向导最后为我们生成了应用程序框架,并在Solution Ex\r\nplorer中自动打开了解决方案。

\"\"

编译运行生成的程序

点菜单中的生成->生成MFCHello,然后点调试->开始执行(不调试)(快捷键Ctrl+F5)运行程序,,这时会弹出对话框提示是否编译,选择“”,VS2010将自动编译链接运行MFCHello程序。结果页面

终于看见界面了。

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2533, 'delete-min', '从顺序表中删除具有最小值的元素并由函数返回被删元素的值。空出的位置由最后一个元素填补,若顺序表为空则显示出错信息并退出运行。', '2013-11-07 06:00:00', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

代码结构:

\"2\"

代码如下:

  1. /*  
  2. ============================================================================  
  3. Name        : SqList.c  
  4. Author      : terwer  
  5. Version     : v1.0  
  6. Copyright   : http://www.xinvalue.com  
  7. Description : SqList in C, Ansi-style  
  8. ============================================================================  
  9. */ 
  10. #include <stdio.h>    
  11. #include <stdlib.h>    
  12.  
  13. #define TRUE 1      
  14. #define FALSE 0     
  15. #define OVERFLOW -2  
  16.  
  17. #define ListSize 100  //表空间的大小可根据实际需要而定,这里假设为100  
  18. typedef int ElemType;//ElemType类型可根据实际情况而定,这里假设为int  
  19. typedef struct {  
  20.     ElemType *data;//向量data用于存放表结点  
  21.     int length;//当前的表长度  
  22. } SqList;  
  23.  
  24. //顺序表的初始化即开辟空间并将表的长度置为0   
  25. void InitList(SqList *L) {  
  26.     L->data=(ElemType*)malloc(sizeof(ElemType)*ListSize);  
  27.     L->length=0;  
  28. }  
  29.  
  30. //求表长只需返回L->length  
  31. int ListLength(SqList *L) {  
  32.     return L->length;  
  33. }  
  34.  
  35. //将新结点e插入L所指的顺序表的第i个结点ai的位置上   
  36. int ListInsert(SqList *L, int i, ElemType e) {  
  37.     if (i<1||i>(L->length+1)) {//非法位置,退出运行   
  38.         return FALSE;  
  39.     }  
  40.     if (L->length>=ListSize) {  
  41.         exit(OVERFLOW); //表空间溢出,退出运行   
  42.     }  
  43.     int j;  
  44.     for (j=L->length; j>=i; j--) {  
  45.         L->data[j]=L->data[j+1];//结点后移  
  46.     }  
  47.     L->data[i-1]=e; //插入e  
  48.     L->length++;//表长加1   
  49.     return TRUE;  
  50. }  
  51.  
  52. void ShowList(SqList L) {  
  53.     int i;  
  54.     for (i=0; i<L.length; i++) {  
  55.         printf("L[%d]=%dn", i, L.data[i]);  
  56.     }  
  57. }  
  58.  
  59. int ListDelete(SqList *L, int i, int *e) {  
  60.     if (i<1||i>L->length) {  
  61.         return FALSE;  
  62.     }  
  63.     *e=L->data[i-1];  
  64.   &#\r\n160; int j;  
  65.     for (j=i; j<L->length; j++) {  
  66.         L->data[i-1]=L->data[i];  
  67.     }  
  68.     L->length--;  
  69.     return TRUE;  
  70. }  
  71.  
  72. //取表中第i个结点只需返回和L->data[i-1]即可   
  73. ElemType GetNode(SqList L, int i) {  
  74.     if (i<1||i> L.length-1)  
  75.         printf("位置错误!");  
  76.     return L.data[i-1];  
  77. }  
  78.  
  79. int LocateElem(SqList L, ElemType e) {  
  80.     int i;  
  81.     for (i=0; i<L.length; i++) {  
  82.         if (L.data[i]==e) {  
  83.             return i+1;  
  84.         }  
  85.     }  
  86.     return 0;  

 

  1. /*  
  2. ============================================================================  
  3. Name        : SqList.c  
  4. Author      : terwer  
  5. Version     : v1.0  
  6. Copyright   : http://www.xinvalue.com  
  7. Description : Main in C, Ansi-style  
  8. ============================================================================  
  9. */ 
  10. #include "SqList.h"  
  11.  
  12. int DeleteMin(SqList *L) {  
  13.     if(L->length==0){  
  14.         printf("顺序表为空!nn");  
  15.         return FALSE;  
  16.     }  
  17.     int end=L->data[L->length-1];  
  18.     int min;  
  19.     int i, k;  
  20.     for (i=L->length; i>0; i--) {  
  21.         if (min>L->data[i-1]) {  
  22.             min=L->data[i-1];  
  23.             k=i;  
  24.         }  
  25.     }  
  26.     L->data[k-1]=end;  
  27.     L->length--;  
  28.     return TRUE;  
  29. }  
  30.  
  31. int main() {  
  32.     SqList s;  
  33.     InitList(&s);  
  34.     ListInsert(&s, 1, 5);  
  35.     ListInsert(&s, 2, 3);  
  36.     ListInsert(&s, 3, 7);  
  37.     ListInsert(&s, 4, 6);  
  38.     ListInsert(&s, 5, 4);  
  39.     printf("操作前:n");  
  40.     ShowList(s);  
  41.     printf("n");  
  42.  
  43.     DeleteMin(&s);  
  44.       
  45.     printf("操作后:n");  
  46.     ShowList(s);  
  47.     return 0;  

效果预览:

\"1\"

代码下载:

\"bdyun\" 

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2534, 'cc-answers', '计算机组成与系统结构课后习题参考答案(白中英第五版)', '2013-11-07 06:00:00', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

\r\n

 软件截图
\"1\" 

\r\n

 安全认证

\r\n

 \"clip_image001_thumb_thumb1\"360通过 \"clip_image0028_thumb1_thumb1\"金山通过\"clip_image0038_thumb_thumb1\"瑞星通过\"clip_image0048_thumb_thumb1\"卡巴通过

\r\n

\"clip_image0058_thumb_thumb1\"小红伞通过 \"clip_image0068_thumb_thumb1\"NOD通过\"clip_image0078_thumb_thumb1\"无插件\"no_thumb1_thumb1\"无病毒

\r\n

\"clip_image0088_thumb_thumb1\"win7兼容 \"clip_image0098_thumb_thumb1\"新价值网认证

\r\n

软件大小

\r\n

3MB

\r\n

下载次数

\r\n

144

\r\n

软件授权

\r\n

免费软件

\r\n

软件语言

\r\n

简体中文

\r\n

开 发 商

\r\n

 本网收集

\r\n

评价等级

\r\n

\"\"\"\"\"\"\"\"\"\"

\r\n

发布时间

\r\n

2013-10-22 19:47:56

\r\n

更新时间

\r\n

2013-10-22 19:47:56

\r\n

软件版本

\r\n

V1.0

\r\n

软件格式

\r\n

pdf

\r\n

应用平台

\r\n

Win7/Vista/Win2003/WinXP/Win2000/

\r\n

软件介绍

\r\n

计算机组成与系统结构课后习题参考答案(白中英第五版)。

\r\n

温馨提示

\r\n

本文档经笔者亲测可用,欢迎下载

\r\n

下载地址

\r\n

下载地址一

\r\n

[reply]

\r\n

 \"bdyun1\" 

\r\n

[/reply]

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2535, 'sqlist', '顺序表的定义及基本操作的实现', '2013-11-06 06:00:00', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】
顺序表的定义

1. 顺序表的定义

(1) 顺序存储方法

即把线性表的结点按逻辑次序依次存放在一组地址连续的存储单元里的方法。

(2) 顺序表(Sequential List)

用顺序存储方法存储的线性表简称为顺序表(Sequential List)。

2. 结点ai 的存储地址

不失一般性,设线性表中所有结点的类型相同,则每个结点所占用存储空间大小亦相同。假设表中每个结点占用c个存储单元,其中第一个单元的存储地址则是该结点的存储地址,并设表中开始结点a1的存储地址(简称为基地址)是LOC(a1),那么结点ai的存储地址LOC(ai)可通过下式计算:
       LOC(ai)= LOC(a1)+(i-1)*c   1≤i≤n

注意:

在顺序表中,每个结点ai的存储地址是该结点在表中的位置i的线性函数。只要知道基地址和每个结点的大小,就可在相同时间内求出任一结点的存储地址。是一种随机存取结构
3.顺序表类型定义

  1. #define ListSize 100  //表空间的大小可根据实际需要而定,这里假设为100  
  2. typedef int ElemType;//ElemType类型可根据实际情况而定,这里假设为int  
  3. typedef struct {  
  4.     ElemType *data;//向量data用于存放表结点  
  5.     int length;//当前的表长度  
  6. } SqList; 

注意:

① 除了用向量这种顺序存储的数组类型存储线性表的元素外,顺序表还应该用一个变量来表示线性表的长度属性,因此用结构类型来定义顺序表类型。

② 存放线性表结点的向量空间的大小ListSize应仔细选值,使其既能满足表结点的数目动态增加的需求,又不致于预先定义过大而浪费存储空间。

③ 由于C语言中向量的下标从0开始,所以若L是SqList类型的顺序表,则线性表的开始结点a1和终端结点an分别存储在L.data[0]和L.data[L.length-1]中。

④ 若L是SqList类型的指针变量,则a1和an分别存储在L->data[0](或(*L).data[0])L->data[L->length-1](或(*L).data[L.length-1])中。
4.顺序表的特点 

顺序表是用向量实现的线性表,向量的下标可以看作结点的相对地址。因此顺序表的的特点是逻辑上相邻的结点其物理位置亦相邻。

顺序表上实现的基本运算
1.表的初始化

  1. //顺序表的初始化即开辟空间并将表的长度置为0  
  2. void InitList(SqList *L) {  
  3.     L->data=(ElemType*)malloc(sizeof(ElemType)*ListSize);  
  4.     L->length=0;  
2.求表长
  1. //求表长只需返回L->length  
  2. int ListLength(SqList *L) {  
  3.     return L->length;  

3.取表中第i个结点 

  1. //取表中第i个结点只需返回和L->data[i-1]即可   
  2. ElemType GetNode(SqList L, int i) {  
  3.     if (i<1||i> L.length-1)  
  4.         printf("位置错误!");  
  5.     return L.data[i-1];  

4.查找值为x的结点 

【参见参考书】
5. 插入
(1) 插入运算的逻辑描述
线性表的插入运算是指在表的第i(1≤i≤n+1)个位置上,插入一个新结点x,使长度为n的线性表: 
(a1,…,ai-1,ai,…an
变成长度为n+1的线性表: 
(a1,…,ai-1,x,ai,…an
注意:

① 由于向量空间大小在声明时确定,当L->length≥ListSize时,表空间已满,不可再做插入操作

② 当插入位置i的值为i>n或i<1时为非法位置,不可做正常插入操作
(2) 顺序表插入操作过程
在顺序表中,结点的物理顺序必须和结点的逻辑顺序保持一致,因此必须将表中位置为n ,n-1,…,i上的结点,依次后移到位置n+1,n,…,i+1上,空出第i个位置,然后在该位置上插入新结点x。仅当插入位置i=n+1时,才无须移动结点,直接将x插入表的末尾。

具体过程见下面动画演示:

(3)具体算法描述

  1. //将新结点e插入L所指的顺序表的第i个结点ai的位置上   
  2. int ListInsert(SqList *L, int i, ElemType e) {  
  3.     if (i<1||i>(L->length+1)) {//非法位置,退出运行   
  4.         return FALSE;  
  5.     }  
  6.     if (L->length>=ListSize) {  
  7.         exit(OVERFLOW); //表空间溢出,退出运行   
  8.     }  
  9.     int j;  
  10.     for (j=L->length; j>=i; j--) {  
  11.         L->data[j]=L->data[j+1];//结点后移  
  12.     }  
  13.     L->data[i-1]=e; //插入e  
  14.     L->length++;//表长加1   
  15.     return TRUE;  

(4)算法分析
① 问题的规模

表的长度L->length(设值为n)是问题的规模。
② 移动结点的次数由表长n和插入位置i决定

算法的时间主要花费在for循环中的结点后移语句上。该语句的执行次数是n-i+1。

当i=n+1:移动结点次数为0,即算法在最好时间复杂度是0(1)

当i=1:移动结点次数为n,即算法在最坏情况下时间复杂度是0(n)
③ 移动结点的平均次数Eis(n)
 

其中:

在表中第i个位置插入一个结点的移动次数为n-i+1

pi表示在表中第i个位置上插入一个结点的概率。不失一般性,假设在表中任何合法位置(1≤i≤n+1)上的插入结点的机会是均等的,则
                 p1=p2=…=pn+1=1/(n+1)

因此,在等概率插入的情况下,
 

即在顺序表上进行插入运算,平均要移动一半结点。

完整的代码如下:

  1. /*  
  2. ============================================================================  
  3. Name        : SqList.c  
  4. Author      : terwer  
  5. Version     : v1.0  
  6. Copyright   : http://www.xinvalue.com  
  7. Description : SqList in C, Ansi-style  
  8. ============================================================================  
  9. */ 
  10. #include <stdio.h>    
  11. #include <stdlib.h>    
  12.  
  13. #define TRUE 1      
  14. #define FALSE 0      
  15.  
  16. #define InitSize 100    
  17.  
  18. typedef int ElemType;  
  19.  
  20. typedef struct {  
  21.     ElemType *data;  
  22.     int length;  
  23. } SqList;  
  24.  
  25. void InitList(SqList *L) {  
  26.     L->data=(ElemType*)malloc(sizeof(ElemType)*InitSize);  
  27.     L->length=0;  
  28. }  
  29.  
  30. int ListInsert(SqList *L, int i, ElemType e) {  
  31.     if (i<1||i>(L->length+1)) {  
  32.         return FALSE;  
  33.     }  
  34.     int j;  
  35.     for (j=L->length; j>=i; j--) {  
  36.         L->data[j]=L->data[j+1];  
  37.     }  
  38.     L->data[i-1]=e;  
  39.     L->length++;  
  40.     return TRUE;  
  41. }  
  42.  
  43. void ShowList(SqList L) {  
  44.     int i;  
  45.     for (i=0; i<L.length; i++) {  
  46.         printf("L[%d]=%dn", i, L.data[i]);  
  47.     }  
  48. }  
  49.  
  50. int ListDelete(SqList *L, int i, int *e) {  
  51.     if (i<1||i>L->length) {  
  52.         return FALSE;  
  53.     }  
  54.     *e=L->data[i-1];  
  55.     int j;  
  56.     for (j=i; j<L->length; j++) {  
  57.         L->data[i-1]=L->data[i];  
  58.     }  
  59.     L->length--;  
  60.     return TRUE;  
  61. }  
  62.  
  63. int LocateElem(SqList L, ElemType e) {  
  64.     int i;  
  65.     for (i=0; i<L.length; i++) {  
  66.         if (L.data[i]==e) {  
  67.             return i+1;  
  68.         }  
  69.     }  
  70.     return 0;  
  71. }  
  72.  
  73. int main() {  
  74.     SqList s;  
  75.     InitList(&s);  
  76.     ListInsert(&s, 1, 5);  
  77.     ListInsert(&s, 2, 3);  
  78.     ListInsert(&s, 3, 7);  
  79.     ShowList(s);  
  80.     printf("n");  
  81.  
  82.     int d=0;  
  83.     ListDelete(&s, 2, &d);  
  84.     printf("删除的元素是:%dnn", d);  
  85.  
  86.     ShowList(s);  
  87.  
  88.     int pos=LocateElem(s, 7);  
  89.     printf("n%dn", pos);  
  90.     return 0;  
  91. }  

效果如下:

\"1\"

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2536, 'csharp-delete-all-txt', 'C# 删除某一个目录中所有的txt文件', '2013-11-05 06:00:00', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

思路,可使用directory和File文件相互结合。

代码如下:

  1. string path = Environment.CurrentDirectory;  
  2.             string pattern = "*.txt";  
  3.             string[] strFileName = Directory.GetFiles(path, pattern);  
  4.             foreach (var item in strFileName)  
  5.             {  
  6.                 File.Delete(item);  
  7.                 Console.WriteLine("{0}文件被删除了",item);  
  8.             }  
  9.             Console.ReadLine(); 
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2537, 'js-alert', '一款漂亮的JS弹窗效果', '2013-11-04 06:00:00', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

代码如下:

  1. <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> 
  2.  
  3. <center><input type="button" style="width:250px;height:60px;font-size:32px;" id="btnTest" value="点击测试"></center> 
  4. <script type="text/javascript"
  5.         $("#btnTest").click(function(){ 
  6.                 sAlert("<div>本网域名是?</div><div><a href=\'http://www.xinvalue.com\'>www.xinValue.com</a>,请牢记哦!</div>"); 
  7.         }); 
  8. </script> 
  9.  
  10.     <script type="text/javascript">   
  11. function sAlert(str) {  
  12.     var msgw, msgh, bordercolor;  
  13.     msgw = 400; //提示窗口的宽度  
  14.     msgh = 100; //提示窗口的高度  
  15.     titleheight = 25; //提示窗口标题高度  
  16.     bordercolor = "#336699"; //提示窗口的边框颜色  
  17.     titlecolor = "#99CCFF"; //提示窗口的标题颜色  
  18.     var sWidth, sHeight;  
  19.     sWidth = document.body.offsetWidth; //浏览器工作区域内页面宽度  
  20.     sHeight = screen.height; //屏幕高度(垂直分辨率)  
  21.   
  22.     //背景层(大小与窗口有效区域相同,即当弹出对话框时,背景显示为放射状透明灰色)  
  23.     var bgObj = document.createElement("div"); //创建一个div对象(背景层)  
  24.     //定义div属性,即相当于  
  25.     //<div id="bgDiv" style="position:absolute; top:0; background-color:#777; filter:progid:DXImagesTransform.Microsoft.Alpha(style=3,opacity=25,finishOpacity=75); opacity:0.6; left:0; width:918px; height:768px; z-index:10000;"></div>  
  26.     bgObj.setAttribute(\'id\', \'bgDiv\');  
  27.     bgObj.style.position = "absolute";  
  28.     bgObj.style.top = "0";  
  29.     bgObj.style.background = "#777";  
  30.     bgObj.style.filter = "progid:DXImageTransform.Microsoft.Alpha(style=3,opacity=25,finishOpacity=75";  
  31.     bgObj.style.opacity = "0.6";  
  32.     bgObj.style.left = "0";  
  33.     bgObj.style.width = sWidth + "px";  
  34.     bgObj.style.height = sHeight + "px";  
  35.     bgObj.style.zIndex = "10000";  
  36.     document.body.appendChild(bgObj); //在body内添加该div对象  
  37.   
  38.     var msgObj = document.createElement("div"); //创建一个div对象(提示框层)  
  39.     //定义div属性,即相当于  
  40.     //<div id="msgDiv" align="center" style="background-color:white; border:1px solid #336699; position:absolute; left:50%; top:50%; font:12px/1.6em Verdana,Geneva,Arial,Helvetica,sans-serif; margin-left:-225px; margin-top:npx; width:400px; height:100px; text-align:center; line-height:25px; z-index:100001;"></div>  
  41.     msgObj.setAttribute("id", "msgDiv");  
  42.     msgObj.setAttribute("align", "center");  
  43.     msgObj.style.background = "white";  
  44.     msgObj.style.border = "1px solid " + bordercolor;  
  45.     msgObj.style.position = "absolute";  
  46.     msgObj.style.left = "50%";  
  47.     msgObj.style.top = "50%";  
  48.     msgObj.style.font = "12px/1.6em Verdana, Geneva, Arial, Helvetica, sans-serif";  
  49.     msgObj.style.marginLeft = "-225px";  
  50.     msgObj.style.marginTop = -75 + document.documentElement.scrollTop + "px";  
  51.     msgObj.style.width = msgw + "px";  
  52.     msgObj.style.height = msgh + "px";  
  53.     msgObj.style.textAlign = "center";  
  54.     msgObj.style.lineHeight = "25px";  
  55.     msgObj.style.zIndex = "10001";  
  56.   
  57.     var title = document.createElement("h4"); //创建一个h4对象(提示框标题栏)  
  58.     //定义h4的属性,即相当于  
  59.     //<h4 id="msgTitle" align="right" style="margin:0; padding:3px; background-color:#336699; filter:progid:DXImageTransform.Microsoft.Alpha(startX=20, startY=20, finishX=100, finishY=100,style=1,opacity=75,finishOpacity=100); opacity:0.75; border:1px solid #336699; height:18px; font:12px Verdana,Geneva,Arial,Helvetica,sans-serif; color:white; cursor:pointer;" onclick="">关闭</h4>  
  60.     title.setAttribute("id", "msgTitle");  
  61.     title.setAttribute("align", "right");  
  62.     title.style.margin = "0";  
  63.     title.style.padding = "3px";  
  64.     title.style.background = bordercolor;  
  65.     title.style.filter = "progid:DXImageTransform.Microsoft.Alpha(startX=20, startY=20, finishX=100, finishY=100,style=1,opacity=75,finishOpacity=100);";  
  66.     title.style.opacity = "0.75";  
  67.     title.style.border = "1px solid " + bordercolor;  
  68.     title.style.height = "18px";  
  69.     title.style.font = "12px Verdana, Geneva, Arial, Helvetica, sans-serif";  
  70.     title.style.color = "white";  
  71.     title.style.cursor = "pointer";  
  72.     title.innerHTML = "关闭";  
  73.     title.onclick = removeObj;  
  74.   
  75.     function removeObj() { //点击标题栏触发的事件  
  76.         document.body.removeChild(bgObj); //删除背景层Div  
  77.         document.getElementById("msgDiv").removeChild(title); //删除提示框的标题栏  
  78.         document.body.removeChild(msgObj); //删除提示框层  
  79.     }  
  80.   
  81.     document.body.appendChild(msgObj); //在body内添加提示框div对象msgObj  
  82.     document.getElementById("msgDiv").appendChild(title); //在提示框div中添加标题栏对象title  
  83.     var txt = document.createElement("p"); //创建一个p对象(提示框提示信息)  
  84.     //定义p的属性,即相当于  
  85.     //<p style="margin:1em 0;" id="msgTxt">测试效果</p>  
  86.     txt.style.margin = "1em 0";  
  87.     txt.setAttribute("id", "msgTxt");  
  88.     txt.innerHTML = str; //来源于函数调用时的参数值  
  89.     document.getElementById("msgDiv").appendChild(txt); //在提示框div中添加提示信息对象txt  
  90.     document.getElementById("msgDiv").appendChild(button); //在提示框div中添加按钮对象button  
  91. }  
  92. </script> 

演示:JS弹出框

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2538, 'min-tree-prim', '最小生成树的普里姆(Prim)算法', '2013-11-03 22:00:16', '2019-03-25 21:29:22', '

\r\n 【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】
\r\n
\r\n

\r\n

\r\n 1)算法思想
\r\n    T=(U,TE)是存放MST的集合。
\r\n  ①T的初值是({r},
Ø)
\r\n    即最小生成树初始时只有一个红点r,没有红边。
\r\n  ②T经过n-1次如下步骤操作,最后得到一棵含n个顶点,n-1条边的最小生成树
\r\n    ⒈选择紫边集中一条轻边并扩充进T
\r\n  ⒉将轻边连接的蓝点改红点
\r\n  ⒊将轻边改红边
\r\n    ⒋修改紫边集
\r\n

\r\n

\r\n 2)较小紫边集的构造
\r\n    若当前形成的T中有k个顶点,|U|=k,|V-u|=n-k,故可能的紫边数目是k(n-k)。从如此大的紫边集中选择轻边是低效的。因此,必须构造较小的紫边集。
\r\n    对于每个蓝点v ∈V-U,从v到各红点的紫边中,只有最短的那一条才有可能是轻边。因此,只须保留所有n-k个蓝点所关联的最短紫边作为轻边的候选集即可。
\r\n
\r\n3)候选紫边集合的修改
\r\n    当把轻边(u,v)扩充到T时,因为v由蓝变红,故对每个剩余的蓝点j,边(v,j)就由非紫边变为紫边,这条新紫边的长度可能小于蓝点j原来所关联的最短紫边的长度。因此,用长度更小的新紫边取代那些原有的最短紫边。
\r\n
\r\n4Prim算法的C语言代码描述
\r\n

\r\n

\r\n 代码结构\r\n

\r\n

\r\n \"\"\r\n

\r\n

\r\n \r\n

\r\n

\r\n \r\n

\r\n

\r\n Basic.h                                                     
\r\n

\r\n\r\n

\r\n
\r\n

\r\n

\r\n
\r\n

\r\n

\r\n \"\"\r\n

\r\n
\r\n
\r\n
\r\n
    \r\n
  1. \r\n /************************************************************************/  \r\n
  2. \r\n
  3. \r\n /* Basic.h                                                              */  \r\n
  4. \r\n
  5. \r\n /* 基本变量定义                                                         */  \r\n
  6. \r\n
  7. \r\n /************************************************************************/  \r\n
  8. \r\n
  9. \r\n #include <string.h>  \r\n
  10. \r\n
  11. \r\n #include <ctype.h>  \r\n
  12. \r\n
  13. \r\n #include <malloc.h> //malloc()等  \r\n
  14. \r\n
  15. \r\n #include <limits.h> //INT_MAX等   \r\n
  16. \r\n
  17. \r\n #include <stdio.h> //EOF(=^Z或F6),NULL   \r\n
  18. \r\n
  19. \r\n #include <stdlib.h> //atoi()   \r\n
  20. \r\n
  21. \r\n #include <io.h> //eof()   \r\n
  22. \r\n
  23. \r\n #include <math.h> //floor(),ceil(),abs()   \r\n
  24. \r\n
  25. \r\n #include <process.h> //exit()   \r\n
  26. \r\n
  27. \r\n //函数结果状态代码   \r\n
  28. \r\n
  29. \r\n #define TRUE 1  \r\n
  30. \r\n
  31. \r\n #define FALSE 0  \r\n
  32. \r\n
  33. \r\n #define OK 1  \r\n
  34. \r\n
  35. \r\n #define ERROR 0  \r\n
  36. \r\n
  37. \r\n #define INFEASIBLE -1  \r\n
  38. \r\n
  39. \r\n //#define OVERFLOW -2 因为在math.h中已定义OVERFLOW的值为3,故去掉此行   \r\n
  40. \r\n
  41. \r\n typedef int Status; //Status是函数的类型,其值是函数结果状态代码,如OK等   \r\n
  42. \r\n
  43. \r\n typedef int Boolean; //Boolean是布尔类型,其值是TRUE或FALSE   \r\n
  44. \r\n
\r\n
\r\n

\r\n
\r\n

\r\n
\r\n

\r\n LinkQueue.h\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n /************************************************************************/  \r\n
  2. \r\n
  3. \r\n /*LinkQueue.h                                                           */  \r\n
  4. \r\n
  5. \r\n /*单链队列--队列的链式存储结构                                        */  \r\n
  6. \r\n
  7. \r\n /************************************************************************/  \r\n
  8. \r\n
  9. \r\n #define OK 1  \r\n
  10. \r\n
  11. \r\n #define ERROR 0  \r\n
  12. \r\n
  13. \r\n #define OVERFLOW 2  \r\n
  14. \r\n
  15. \r\n typedef int Status;  \r\n
  16. \r\n
  17. \r\n typedef int QElemType;  \r\n
  18. \r\n
  19. \r\n   \r\n
  20. \r\n
  21. \r\n typedef struct QNode {  \r\n
  22. \r\n
  23. \r\n     QElemType data;  \r\n
  24. \r\n
  25. \r\n     struct QNode *next;  \r\n
  26. \r\n
  27. \r\n } QNode, *QueuePtr;  \r\n
  28. \r\n
  29. \r\n   \r\n
  30. \r\n
  31. \r\n typedef struct {  \r\n
  32. \r\n
  33. \r\n     QueuePtr front, rear; //队头、队尾指针  \r\n
  34. \r\n
  35. \r\n } LinkQueue;  \r\n
  36. \r\n
  37. \r\n   \r\n
  38. \r\n
  39. \r\n /************************************************************************/  \r\n
  40. \r\n
  41. \r\n /* 链队列的基本操作(9个)                                                 */  \r\n
  42. \r\n
  43. \r\n /************************************************************************/   \r\n
  44. \r\n
  45. \r\n   \r\n
  46. \r\n
  47. \r\n //构造一个空队列Q  \r\n
  48. \r\n
  49. \r\n Status InitQueue(LinkQueue *Q){   \r\n
  50. \r\n
  51. \r\n     (*Q).front=(*Q).rear=(QueuePtr)malloc(sizeof(QNode));  \r\n
  52. \r\n
  53. \r\n     if(!(*Q).front)  \r\n
  54. \r\n
  55. \r\n         exit(OVERFLOW);  \r\n
  56. \r\n
  57. \r\n     (*Q).front->next=NULL;  \r\n
  58. \r\n
  59. \r\n     return OK;  \r\n
  60. \r\n
  61. \r\n }  \r\n
  62. \r\n
  63. \r\n   \r\n
  64. \r\n
  65. \r\n //销毁队列Q(无论空否均可)   \r\n
  66. \r\n
  67. \r\n Status DestroyQueue(LinkQueue *Q){  \r\n
  68. \r\n
  69. \r\n     while((*Q).front){  \r\n
  70. \r\n
  71. \r\n         (*Q).rear=(*Q).front->next;  \r\n
  72. \r\n
  73. \r\n         free((*Q).front);  \r\n
  74. \r\n
  75. \r\n         (*Q).front=(*Q).rear;  \r\n
  76. \r\n
  77. \r\n     }  \r\n
  78. \r\n
  79. \r\n     return OK;  \r\n
  80. \r\n
  81. \r\n }  \r\n
  82. \r\n
  83. \r\n   \r\n
  84. \r\n
  85. \r\n //将Q清为空队列  \r\n
  86. \r\n
  87. \r\n Status ClearQueue(LinkQueue *Q){  \r\n
  88. \r\n
  89. \r\n     QueuePtr p,q;  \r\n
  90. \r\n
  91. \r\n     (*Q).rear=(*Q).front;  \r\n
  92. \r\n
  93. \r\n     p=(*Q).front->next;  \r\n
  94. \r\n
  95. \r\n     (*Q).front->next=NULL;  \r\n
  96. \r\n
  97. \r\n     while(p){  \r\n
  98. \r\n
  99. \r\n         q=p;  \r\n
  100. \r\n
  101. \r\n         p=p->next;  \r\n
  102. \r\n
  103. \r\n         free(q);  \r\n
  104. \r\n
  105. \r\n     }  \r\n
  106. \r\n
  107. \r\n     return OK;  \r\n
  108. \r\n
  109. \r\n }  \r\n
  110. \r\n
  111. \r\n   \r\n
  112. \r\n
  113. \r\n //若Q为空队列,则返回TRUE,否则返回FALSE  \r\n
  114. \r\n
  115. \r\n Status QueueEmpty(LinkQueue Q){  \r\n
  116. \r\n
  117. \r\n     if(Q.front==Q.rear)  \r\n
  118. \r\n
  119. \r\n         return TRUE;  \r\n
  120. \r\n
  121. \r\n     else  \r\n
  122. \r\n
  123. \r\n         return FALSE;  \r\n
  124. \r\n
  125. \r\n }  \r\n
  126. \r\n
  127. \r\n   \r\n
  128. \r\n
  129. \r\n //求队列的长度  \r\n
  130. \r\n
  131. \r\n int QueueLength(LinkQueue Q){   \r\n
  132. \r\n
  133. \r\n     int i=0;  \r\n
  134. \r\n
  135. \r\n     QueuePtr p;  \r\n
  136. \r\n
  137. \r\n     p=Q.front;  \r\n
  138. \r\n
  139. \r\n     while(Q.rear!=p) {  \r\n
  140. \r\n
  141. \r\n         i++;  \r\n
  142. \r\n
  143. \r\n         p=p->next;  \r\n
  144. \r\n
  145. \r\n     }  \r\n
  146. \r\n
  147. \r\n     return i;  \r\n
  148. \r\n
  149. \r\n }  \r\n
  150. \r\n
  151. \r\n   \r\n
  152. \r\n
  153. \r\n //若队列不空,则用e返回Q的队头元素,并返回OK,否则返回ERROR  \r\n
  154. \r\n
  155. \r\n Status GetHead_Q(LinkQueue Q,QElemType *e) {   \r\n
  156. \r\n
  157. \r\n     QueuePtr p;  \r\n
  158. \r\n
  159. \r\n     if(Q.front==Q.rear)  \r\n
  160. \r\n
  161. \r\n         return ERROR;  \r\n
  162. \r\n
  163. \r\n     p=Q.front->next;  \r\n
  164. \r\n
  165. \r\n     *e=p->data;  \r\n
  166. \r\n
  167. \r\n     return OK;  \r\n
  168. \r\n
  169. \r\n }  \r\n
  170. \r\n
  171. \r\n   \r\n
  172. \r\n
  173. \r\n //插入元素e为Q的新的队尾元素  \r\n
  174. \r\n
  175. \r\n Status EnQueue(LinkQueue *Q,QElemType e)  \r\n
  176. \r\n
  177. \r\n {   \r\n
  178. \r\n
  179. \r\n     QueuePtr p=(QueuePtr)malloc(sizeof(QNode));  \r\n
  180. \r\n
  181. \r\n     if(!p) //存储分配失败  \r\n
  182. \r\n
  183. \r\n         exit(OVERFLOW);  \r\n
  184. \r\n
  185. \r\n     p->data=e;  \r\n
  186. \r\n
  187. \r\n     p->next=NULL;  \r\n
  188. \r\n
  189. \r\n     (*Q).rear->next=p;  \r\n
  190. \r\n
  191. \r\n     (*Q).rear=p;  \r\n
  192. \r\n
  193. \r\n     return OK;  \r\n
  194. \r\n
  195. \r\n }  \r\n
  196. \r\n
  197. \r\n   \r\n
  198. \r\n
  199. \r\n //若队列不空,删除Q的队头元素,用e返回其值,并返回OK,否则返回ERROR  \r\n
  200. \r\n
  201. \r\n Status DeQueue(LinkQueue *Q,QElemType *e)  \r\n
  202. \r\n
  203. \r\n {   \r\n
  204. \r\n
  205. \r\n     QueuePtr p;  \r\n
  206. \r\n
  207. \r\n     if((*Q).front==(*Q).rear)  \r\n
  208. \r\n
  209. \r\n         return ERROR;  \r\n
  210. \r\n
  211. \r\n     p=(*Q).front->next;  \r\n
  212. \r\n
  213. \r\n     *e=p->data;  \r\n
  214. \r\n
  215. \r\n     (*Q).front->next=p->next;  \r\n
  216. \r\n
  217. \r\n     if((*Q).rear==p)  \r\n
  218. \r\n
  219. \r\n         (*Q).rear=(*Q).front;  \r\n
  220. \r\n
  221. \r\n     free(p);  \r\n
  222. \r\n
  223. \r\n     return OK;  \r\n
  224. \r\n
  225. \r\n }  \r\n
  226. \r\n
  227. \r\n   \r\n
  228. \r\n
  229. \r\n //从队头到队尾依次对队列Q中每个元素调用函数vi()。一旦vi失败,则操作失败。  \r\n
  230. \r\n
  231. \r\n Status QueueTraverse(LinkQueue Q,void(*vi)(QElemType)){  \r\n
  232. \r\n
  233. \r\n     QueuePtr p;  \r\n
  234. \r\n
  235. \r\n     p=Q.front->next;  \r\n
  236. \r\n
  237. \r\n     while(p){  \r\n
  238. \r\n
  239. \r\n         vi(p->data);  \r\n
  240. \r\n
  241. \r\n         p=p->next;  \r\n
  242. \r\n
  243. \r\n     }  \r\n
  244. \r\n
  245. \r\n     printf(\"n\");  \r\n
  246. \r\n
  247. \r\n     return OK;  \r\n
  248. \r\n
  249. \r\n }  \r\n
  250. \r\n
\r\n
\r\n
\r\n
\r\n
\r\n

\r\n MGraph.h\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n /************************************************************************/  \r\n
  2. \r\n
  3. \r\n /*MGraph.h                                                              */  \r\n
  4. \r\n
  5. \r\n /*图的数组(邻接矩阵)存储表示                                          */                         \r\n
  6. \r\n
  7. \r\n /************************************************************************/  \r\n
  8. \r\n
  9. \r\n //#define INT_MAX 99999 //库函数已经定义了  \r\n
  10. \r\n
  11. \r\n //#define INFINITY INT_MAX //整型最大值代替∞  \r\n
  12. \r\n
  13. \r\n #define INFINITY 99999 //99999代替∞  \r\n
  14. \r\n
  15. \r\n #define MAX_VERTEX_NUM 20 //最大顶点个数  \r\n
  16. \r\n
  17. \r\n   \r\n
  18. \r\n
  19. \r\n typedef enum {DG,DN,UDG,UDN} GraphKind; //{有向图,有向网,无向图,无向网}   \r\n
  20. \r\n
  21. \r\n typedef struct {  \r\n
  22. \r\n
  23. \r\n     VRType adj; //顶点关系类型。对无权图,用1(是)或0(否)表示相邻否; 对带权图,c则为权值类型  \r\n
  24. \r\n
  25. \r\n     InfoType *info; //该弧相关信息的指针(可无)  \r\n
  26. \r\n
  27. \r\n } ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];  \r\n
  28. \r\n
  29. \r\n typedef struct {  \r\n
  30. \r\n
  31. \r\n     VertexType vexs[MAX_VERTEX_NUM]; //顶点向量  \r\n
  32. \r\n
  33. \r\n     AdjMatrix arcs; //邻接矩阵  \r\n
  34. \r\n
  35. \r\n     int vexnum, arcnum; //图的当前顶点数和弧数  \r\n
  36. \r\n
  37. \r\n     GraphKind kind; //图的种类标志  \r\n
  38. \r\n
  39. \r\n } MGraph;  \r\n
  40. \r\n
  41. \r\n   \r\n
  42. \r\n
  43. \r\n /************************************************************************/  \r\n
  44. \r\n
  45. \r\n /*图的数组(邻接矩阵)存储的基本操作(20个)                                  */  \r\n
  46. \r\n
  47. \r\n /************************************************************************/  \r\n
  48. \r\n
  49. \r\n   \r\n
  50. \r\n
  51. \r\n //初始条件:图G存在,u和G中顶点有相同特征  \r\n
  52. \r\n
  53. \r\n //操作结果:若G中存在顶点u,则返回该顶点在图中位置;否则返回-1  \r\n
  54. \r\n
  55. \r\n int LocateVex(MGraph G, VertexType u) {  \r\n
  56. \r\n
  57. \r\n     int i;  \r\n
  58. \r\n
  59. \r\n     for (i=0; i<G.vexnum; ++i)  \r\n
  60. \r\n
  61. \r\n         if (strcmp(u, G.vexs[i])==0)  \r\n
  62. \r\n
  63. \r\n             return i;  \r\n
  64. \r\n
  65. \r\n     return -1;  \r\n
  66. \r\n
  67. \r\n }  \r\n
  68. \r\n
  69. \r\n   \r\n
  70. \r\n
  71. \r\n //采用数组(邻接矩阵)表示法,构造有向图G,构造成功返回1  \r\n
  72. \r\n
  73. \r\n Status CreateDG(MGraph *G) {  \r\n
  74. \r\n
  75. \r\n     int i, j, k, l, IncInfo;  \r\n
  76. \r\n
  77. \r\n     char s[MAX_INFO], *info;  \r\n
  78. \r\n
  79. \r\n     VertexType va, vb;  \r\n
  80. \r\n
  81. \r\n     printf(\"请输入有向图G的顶点数、弧数、弧是否含其它信息(是:1,否:0),以空格隔开:n\");  \r\n
  82. \r\n
  83. \r\n     scanf(\"%d%d%d\", &(*G).vexnum, &(*G).arcnum, &IncInfo);  \r\n
  84. \r\n
  85. \r\n     //构造顶点向量  \r\n
  86. \r\n
  87. \r\n     for (i=0; i<(*G).vexnum; ++i) {  \r\n
  88. \r\n
  89. \r\n         printf(\"请输入第%d个顶点的值(<%d个字符):n\", i+1, MAX_NAME);  \r\n
  90. \r\n
  91. \r\n         scanf(\"%s\", (*G).vexs[i]);  \r\n
  92. \r\n
  93. \r\n     }  \r\n
  94. \r\n
  95. \r\n     //初始化邻接矩阵  \r\n
  96. \r\n
  97. \r\n     for (i=0; i<(*G).vexnum; ++i)  \r\n
  98. \r\n
  99. \r\n         for (j=0; j<(*G).vexnum; ++j) {  \r\n
  100. \r\n
  101. \r\n             (*G).arcs[i][j].adj=0;//图  \r\n
  102. \r\n
  103. \r\n             (*G).arcs[i][j].info=NULL;  \r\n
  104. \r\n
  105. \r\n         }  \r\n
  106. \r\n
  107. \r\n         //输入结点之间的联系  \r\n
  108. \r\n
  109. \r\n         for (k=0; k<(*G).arcnum; ++k) {  \r\n
  110. \r\n
  111. \r\n             printf(\"请输入第%d条弧的弧尾、弧头(以空格作为间隔): n\", k+1);  \r\n
  112. \r\n
  113. \r\n             scanf(\"%s%s%*c\", va, vb); //%*c吃掉回车符  \r\n
  114. \r\n
  115. \r\n             i=LocateVex(*G, va);  \r\n
  116. \r\n
  117. \r\n             j=LocateVex(*G, vb);  \r\n
  118. \r\n
  119. \r\n             (*G).arcs[i][j].adj=1; //有向图  \r\n
  120. \r\n
  121. \r\n             if (IncInfo) {  \r\n
  122. \r\n
  123. \r\n                 printf(\"请输入该弧的相关信息(<%d个字符): \", MAX_INFO);  \r\n
  124. \r\n
  125. \r\n                 gets(s);  \r\n
  126. \r\n
  127. \r\n                 l=strlen(s);  \r\n
  128. \r\n
  129. \r\n                 if (l) {  \r\n
  130. \r\n
  131. \r\n                     info=(char*)malloc((l+1)*sizeof(char));  \r\n
  132. \r\n
  133. \r\n                     strcpy(info, s);  \r\n
  134. \r\n
  135. \r\n                     (*G).arcs[i][j].info=info; //有向  \r\n
  136. \r\n
  137. \r\n                 }  \r\n
  138. \r\n
  139. \r\n             }  \r\n
  140. \r\n
  141. \r\n         }  \r\n
  142. \r\n
  143. \r\n         (*G).kind=DG;  \r\n
  144. \r\n
  145. \r\n         return OK;  \r\n
  146. \r\n
  147. \r\n }  \r\n
  148. \r\n
  149. \r\n   \r\n
  150. \r\n
  151. \r\n //采用数组(邻接矩阵)表示法,构造有向网G,构造成功返回1  \r\n
  152. \r\n
  153. \r\n Status CreateDN(MGraph *G) {  \r\n
  154. \r\n
  155. \r\n     int i, j, k, w, IncInfo;  \r\n
  156. \r\n
  157. \r\n     char s[MAX_INFO], *info;  \r\n
  158. \r\n
  159. \r\n     VertexType va, vb;  \r\n
  160. \r\n
  161. \r\n     printf(\"请输入有向网G的顶点数、弧数、弧是否含其它信息(是:1,否:0): \");  \r\n
  162. \r\n
  163. \r\n     scanf(\"%d%d%d\", &(*G).vexnum, &(*G).arcnum, &IncInfo);  \r\n
  164. \r\n
  165. \r\n     //构造顶点向量  \r\n
  166. \r\n
  167. \r\n     for (i=0; i<(*G).vexnum; ++i) {  \r\n
  168. \r\n
  169. \r\n         printf(\"请输入第%d个顶点的值(<%d个字符):n\", i+1, MAX_NAME);  \r\n
  170. \r\n
  171. \r\n         scanf(\"%s\", (*G).vexs[i]);  \r\n
  172. \r\n
  173. \r\n     }  \r\n
  174. \r\n
  175. \r\n     //初始化邻接矩阵  \r\n
  176. \r\n
  177. \r\n     for (i=0; i<(*G).vexnum; ++i)  \r\n
  178. \r\n
  179. \r\n         for (j=0; j<(*G).vexnum; ++j) {  \r\n
  180. \r\n
  181. \r\n             (*G).arcs[i][j].adj=INFINITY; //网  \r\n
  182. \r\n
  183. \r\n             (*G).arcs[i][j].info=NULL;  \r\n
  184. \r\n
  185. \r\n         }  \r\n
  186. \r\n
  187. \r\n         for (k=0; k<(*G).arcnum; ++k) {  \r\n
  188. \r\n
  189. \r\n             printf(\"请输入第%d条弧的弧尾、弧头、权值(以空格作为间隔): n\", k+1);  \r\n
  190. \r\n
  191. \r\n             scanf(\"%s%s%d%*c\", va, vb, &w); //%*c吃掉回车符  \r\n
  192. \r\n
  193. \r\n             i=LocateVex(*G, va);  \r\n
  194. \r\n
  195. \r\n             j=LocateVex(*G, vb);  \r\n
  196. \r\n
  197. \r\n             (*G).arcs[i][j].adj=w; //有向网  \r\n
  198. \r\n
  199. \r\n             if (IncInfo) {  \r\n
  200. \r\n
  201. \r\n                 printf(\"请输入该弧的相关信息(<%d个字符): \", MAX_INFO);  \r\n
  202. \r\n
  203. \r\n                 gets(s);  \r\n
  204. \r\n
  205. \r\n                 w=strlen(s);  \r\n
  206. \r\n
  207. \r\n                 if (w) {  \r\n
  208. \r\n
  209. \r\n                     info=(char*)malloc((w+1)*sizeof(char));  \r\n
  210. \r\n
  211. \r\n                     strcpy(info, s);  \r\n
  212. \r\n
  213. \r\n                     (*G).arcs[i][j].info=info; //有向  \r\n
  214. \r\n
  215. \r\n                 }  \r\n
  216. \r\n
  217. \r\n             }  \r\n
  218. \r\n
  219. \r\n         }  \r\n
  220. \r\n
  221. \r\n         (*G).kind=DN;  \r\n
  222. \r\n
  223. \r\n         return OK;  \r\n
  224. \r\n
  225. \r\n }  \r\n
  226. \r\n
  227. \r\n   \r\n
  228. \r\n
  229. \r\n //采用数组(邻接矩阵)表示法,构造无向图G,构造成功返回1  \r\n
  230. \r\n
  231. \r\n Status CreateUDG(MGraph *G) {   \r\n
  232. \r\n
  233. \r\n     int i, j, k, l, IncInfo;  \r\n
  234. \r\n
  235. \r\n     char s[MAX_INFO], *info;  \r\n
  236. \r\n
  237. \r\n     VertexType va, vb;  \r\n
  238. \r\n
  239. \r\n     printf(\"请输入无向图G的顶点数、边数、边是否含其它信息(是:1,否:0): \");  \r\n
  240. \r\n
  241. \r\n     scanf(\"%d%d%d\", &(*G).vexnum, &(*G).arcnum, &IncInfo);  \r\n
  242. \r\n
  243. \r\n     //构造顶点向量  \r\n
  244. \r\n
  245. \r\n     for (i=0; i<(*G).vexnum; ++i) {  \r\n
  246. \r\n
  247. \r\n         printf(\"请输入第%d个顶点的值(<%d个字符):n\", i+1, MAX_NAME);  \r\n
  248. \r\n
  249. \r\n         scanf(\"%s\", (*G).vexs[i]);  \r\n
  250. \r\n
  251. \r\n     }  \r\n
  252. \r\n
  253. \r\n     //初始化邻接矩阵  \r\n
  254. \r\n
  255. \r\n     for (i=0; i<(*G).vexnum; ++i)  \r\n
  256. \r\n
  257. \r\n         for (j=0; j<(*G).vexnum; ++j) {  \r\n
  258. \r\n
  259. \r\n             (*G).arcs[i][j].adj=0; //图  \r\n
  260. \r\n
  261. \r\n             (*G).arcs[i][j].info=NULL;  \r\n
  262. \r\n
  263. \r\n         }  \r\n
  264. \r\n
  265. \r\n         //输入结点之间的联系  \r\n
  266. \r\n
  267. \r\n         for (k=0; k<(*G).arcnum; ++k) {  \r\n
  268. \r\n
  269. \r\n             printf(\"请输入第%d条边的顶点1、顶点2(以空格作为间隔): n\", k+1);  \r\n
  270. \r\n
  271. \r\n             scanf(\"%s%s\", va, vb); //%*c吃掉回车符  \r\n
  272. \r\n
  273. \r\n             i=LocateVex(*G, va);  \r\n
  274. \r\n
  275. \r\n             j=LocateVex(*G, vb);  \r\n
  276. \r\n
  277. \r\n             (*G).arcs[i][j].adj=(*G).arcs[j][i].adj=1; //无向图  \r\n
  278. \r\n
  279. \r\n             if (IncInfo)  \r\n
  280. \r\n
  281. \r\n                 printf(\"请输入该边的相关信息(<%d个字符): \", MAX_INFO);  \r\n
  282. \r\n
  283. \r\n             gets(s);  \r\n
  284. \r\n
  285. \r\n             l=strlen(s);  \r\n
  286. \r\n
  287. \r\n             if (l) {  \r\n
  288. \r\n
  289. \r\n                 info=(char*)malloc((l+1)*sizeof(char));  \r\n
  290. \r\n
  291. \r\n                 strcpy(info, s);  \r\n
  292. \r\n
  293. \r\n                 (*G).arcs[i][j].info=(*G).arcs[j][i].info=info; //无向  \r\n
  294. \r\n
  295. \r\n             }  \r\n
  296. \r\n
  297. \r\n         }  \r\n
  298. \r\n
  299. \r\n         (*G).kind=UDG;  \r\n
  300. \r\n
  301. \r\n         return OK;  \r\n
  302. \r\n
  303. \r\n }  \r\n
  304. \r\n
  305. \r\n   \r\n
  306. \r\n
  307. \r\n //采用数组(邻接矩阵)表示法,构造无向网G,构造成功返回1。算法7.2   \r\n
  308. \r\n
  309. \r\n Status CreateUDN(MGraph *G) {   \r\n
  310. \r\n
  311. \r\n     int i, j, k, w, IncInfo;  \r\n
  312. \r\n
  313. \r\n     char s[MAX_INFO], *info;  \r\n
  314. \r\n
  315. \r\n     VertexType va, vb;  \r\n
  316. \r\n
  317. \r\n     printf(\"请输入无向网G的顶点数,边数,边是否含其它信息(是:1,否:0): \");  \r\n
  318. \r\n
  319. \r\n     scanf(\"%d%d%d\", &(*G).vexnum, &(*G).arcnum, &IncInfo);  \r\n
  320. \r\n
  321. \r\n     //构造顶点向量   \r\n
  322. \r\n
  323. \r\n     for (i=0; i<(*G).vexnum; ++i) {  \r\n
  324. \r\n
  325. \r\n         printf(\"请输入第%d个顶点的值(<%d个字符):n\", i+1, MAX_NAME);  \r\n
  326. \r\n
  327. \r\n         scanf(\"%s\", (*G).vexs[i]);  \r\n
  328. \r\n
  329. \r\n     }  \r\n
  330. \r\n
  331. \r\n     //初始化邻接矩阵  \r\n
  332. \r\n
  333. \r\n     for (i=0; i<(*G).vexnum; ++i)  \r\n
  334. \r\n
  335. \r\n         for (j=0; j<(*G).vexnum; ++j) {  \r\n
  336. \r\n
  337. \r\n             (*G).arcs[i][j].adj=INFINITY; //网   \r\n
  338. \r\n
  339. \r\n             (*G).arcs[i][j].info=NULL;  \r\n
  340. \r\n
  341. \r\n         }  \r\n
  342. \r\n
  343. \r\n         //输入结点之间的联系  \r\n
  344. \r\n
  345. \r\n         for (k=0; k<(*G).arcnum; ++k) {  \r\n
  346. \r\n
  347. \r\n             printf(\"请输入第%d条边的顶点1、顶点2、权值(以空格作为间隔): n\", k+1);  \r\n
  348. \r\n
  349. \r\n             scanf(\"%s%s%d%*c\", va, vb, &w); //%*c吃掉回车符  \r\n
  350. \r\n
  351. \r\n             i=LocateVex(*G, va);  \r\n
  352. \r\n
  353. \r\n             j=LocateVex(*G, vb);  \r\n
  354. \r\n
  355. \r\n             (*G).arcs[i][j].adj=(*G).arcs[j][i].adj=w; //无向  \r\n
  356. \r\n
  357. \r\n             if (IncInfo) {  \r\n
  358. \r\n
  359. \r\n                 printf(\"请输入该边的相关信息(<%d个字符): \", MAX_INFO);  \r\n
  360. \r\n
  361. \r\n                 gets(s);  \r\n
  362. \r\n
  363. \r\n                 w=strlen(s);  \r\n
  364. \r\n
  365. \r\n                 if (w) {  \r\n
  366. \r\n
  367. \r\n                     info=(char*)malloc((w+1)*sizeof(char));  \r\n
  368. \r\n
  369. \r\n                     strcpy(info, s);  \r\n
  370. \r\n
  371. \r\n                     (*G).arcs[i][j].info=(*G).arcs[j][i].info=info; //无向  \r\n
  372. \r\n
  373. \r\n                 }  \r\n
  374. \r\n
  375. \r\n             }  \r\n
  376. \r\n
  377. \r\n         }  \r\n
  378. \r\n
  379. \r\n         (*G).kind=UDN;  \r\n
  380. \r\n
  381. \r\n         return OK;  \r\n
  382. \r\n
  383. \r\n }  \r\n
  384. \r\n
  385. \r\n   \r\n
  386. \r\n
  387. \r\n //采用数组(邻接矩阵)表示法,构造图G。算法7.1  \r\n
  388. \r\n
  389. \r\n //参数1:MGraph *G。  \r\n
  390. \r\n
  391. \r\n //返回值:创建成功返回1,失败返回0。  \r\n
  392. \r\n
  393. \r\n Status CreateGraph(MGraph *G) {       \r\n
  394. \r\n
  395. \r\n     printf(\"请输入图G的类型:n0:有向图n1:有向网n2:无向图n3:无向网n\");  \r\n
  396. \r\n
  397. \r\n     scanf(\"%d\", &(*G).kind);  \r\n
  398. \r\n
  399. \r\n     switch ((*G).kind) {  \r\n
  400. \r\n
  401. \r\n     case DG:  \r\n
  402. \r\n
  403. \r\n         return CreateDG(G); //构造有向图  \r\n
  404. \r\n
  405. \r\n     case DN:  \r\n
  406. \r\n
  407. \r\n         return CreateDN(G); //构造有向网  \r\n
  408. \r\n
  409. \r\n     case UDG:  \r\n
  410. \r\n
  411. \r\n         return CreateUDG(G); //构造无向图  \r\n
  412. \r\n
  413. \r\n     case UDN:  \r\n
  414. \r\n
  415. \r\n         return CreateUDN(G); //构造无向网  \r\n
  416. \r\n
  417. \r\n     default:  \r\n
  418. \r\n
  419. \r\n         return ERROR;  \r\n
  420. \r\n
  421. \r\n     }  \r\n
  422. \r\n
  423. \r\n }  \r\n
  424. \r\n
  425. \r\n   \r\n
  426. \r\n
  427. \r\n //初始条件: 图G存在。  \r\n
  428. \r\n
  429. \r\n //操作结果: 销毁图G   \r\n
  430. \r\n
  431. \r\n void DestroyGraph(MGraph *G) {  \r\n
  432. \r\n
  433. \r\n     int i, j;  \r\n
  434. \r\n
  435. \r\n     if ((*G).kind<2) //有向   \r\n
  436. \r\n
  437. \r\n         for (i=0; i<(*G).vexnum; i++) //释放弧的相关信息(如果有的话)  \r\n
  438. \r\n
  439. \r\n         {  \r\n
  440. \r\n
  441. \r\n             for (j=0; j<(*G).vexnum; j++)  \r\n
  442. \r\n
  443. \r\n                 if ((*G).arcs[i][j].adj==1&&(*G).kind==0||(*G).arcs[i][j].adj!=INFINITY&&(*G).kind==1) //有向图的弧||有向网的弧  \r\n
  444. \r\n
  445. \r\n                     if ((*G).arcs[i][j].info) //有相关信息  \r\n
  446. \r\n
  447. \r\n                     {  \r\n
  448. \r\n
  449. \r\n                         free((*G).arcs[i][j].info);  \r\n
  450. \r\n
  451. \r\n                         (*G).arcs[i][j].info=NULL;  \r\n
  452. \r\n
  453. \r\n                     }  \r\n
  454. \r\n
  455. \r\n         }  \r\n
  456. \r\n
  457. \r\n     else  \r\n
  458. \r\n
  459. \r\n         //无向   \r\n
  460. \r\n
  461. \r\n         for (i=0; i<(*G).vexnum; i++)  \r\n
  462. \r\n
  463. \r\n             //释放边的相关信息(如果有的话)  \r\n
  464. \r\n
  465. \r\n             for (j=i+1; j<(*G).vexnum; j++)  \r\n
  466. \r\n
  467. \r\n                 if ((*G).arcs[i][j].adj==1&&(*G).kind==2||(*G).arcs[i][j].adj!=INFINITY&&(*G).kind==3) //无向图的边||无向网的边   \r\n
  468. \r\n
  469. \r\n                     //有相关信息  \r\n
  470. \r\n
  471. \r\n                     if ((*G).arcs[i][j].info)  {  \r\n
  472. \r\n
  473. \r\n                         free((*G).arcs[i][j].info);  \r\n
  474. \r\n
  475. \r\n                         (*G).arcs[i][j].info=(*G).arcs[j][i].info=NULL;  \r\n
  476. \r\n
  477. \r\n                     }  \r\n
  478. \r\n
  479. \r\n                     (*G).vexnum=0;  \r\n
  480. \r\n
  481. \r\n                     (*G).arcnum=0;  \r\n
  482. \r\n
  483. \r\n }  \r\n
  484. \r\n
  485. \r\n   \r\n
  486. \r\n
  487. \r\n //初始条件: 图G存在,v是G中某个顶点的序号。  \r\n
  488. \r\n
  489. \r\n //操作结果: 返回v的值   \r\n
  490. \r\n
  491. \r\n VertexType* GetVex(MGraph G, int v) {   \r\n
  492. \r\n
  493. \r\n     if (v>=G.vexnum||v<0)  \r\n
  494. \r\n
  495. \r\n         exit(ERROR);  \r\n
  496. \r\n
  497. \r\n     return &G.vexs[v];  \r\n
  498. \r\n
  499. \r\n }  \r\n
  500. \r\n
  501. \r\n   \r\n
  502. \r\n
  503. \r\n //初始条件: 图G存在,v是G中某个顶点。  \r\n
  504. \r\n
  505. \r\n //操作结果: 对v赋新值value  \r\n
  506. \r\n
  507. \r\n Status PutVex(MGraph *G, VertexType v, VertexType value) {  \r\n
  508. \r\n
  509. \r\n     int k;  \r\n
  510. \r\n
  511. \r\n     k=LocateVex(*G, v); //k为顶点v在图G中的序号  \r\n
  512. \r\n
  513. \r\n     if (k<0)  \r\n
  514. \r\n
  515. \r\n         return ERROR;  \r\n
  516. \r\n
  517. \r\n     strcpy((*G).vexs[k], value);  \r\n
  518. \r\n
  519. \r\n     return OK;  \r\n
  520. \r\n
  521. \r\n }  \r\n
  522. \r\n
  523. \r\n   \r\n
  524. \r\n
  525. \r\n //初始条件: 图G存在,v是G中某个顶点   \r\n
  526. \r\n
  527. \r\n //操作结果: 返回v的第一个邻接顶点的序号。若顶点在G中没有邻接顶点,则返回-1  \r\n
  528. \r\n
  529. \r\n int FirstAdjVex(MGraph G, VertexType v) {   \r\n
  530. \r\n
  531. \r\n     int i, j=0, k;  \r\n
  532. \r\n
  533. \r\n     k=LocateVex(G, v); //k为顶点v在图G中的序号   \r\n
  534. \r\n
  535. \r\n     if (G.kind==DN||G.kind==UDN) //网   \r\n
  536. \r\n
  537. \r\n         j=INFINITY;  \r\n
  538. \r\n
  539. \r\n     for (i=0; i<G.vexnum; i++)  \r\n
  540. \r\n
  541. \r\n         if (G.arcs[k][i].adj!=j)  \r\n
  542. \r\n
  543. \r\n             return i;  \r\n
  544. \r\n
  545. \r\n     return -1;  \r\n
  546. \r\n
  547. \r\n }  \r\n
  548. \r\n
  549. \r\n   \r\n
  550. \r\n
  551. \r\n //初始条件: 图G存在,v是G中某个顶点,w是v的邻接顶点  \r\n
  552. \r\n
  553. \r\n //操作结果: 返回v的(相对于w的)下一个邻接顶点的序号,若w是v的最后一个邻接顶点,则返回-1   \r\n
  554. \r\n
  555. \r\n int NextAdjVex(MGraph G, VertexType v, VertexType w) {   \r\n
  556. \r\n
  557. \r\n     int i, j=0, k1, k2;  \r\n
  558. \r\n
  559. \r\n     k1=LocateVex(G, v); //k1为顶点v在图G中的序号   \r\n
  560. \r\n
  561. \r\n     k2=LocateVex(G, w); //k2为顶点w在图G中的序号   \r\n
  562. \r\n
  563. \r\n     if (G.kind==DN||G.kind==UDN) //网  \r\n
  564. \r\n
  565. \r\n         j=INFINITY;  \r\n
  566. \r\n
  567. \r\n     for (i=k2+1; i<G.vexnum; i++)  \r\n
  568. \r\n
  569. \r\n         if (G.arcs[k1][i].adj!=j)  \r\n
  570. \r\n
  571. \r\n             return i;  \r\n
  572. \r\n
  573. \r\n     return -1;  \r\n
  574. \r\n
  575. \r\n }  \r\n
  576. \r\n
  577. \r\n   \r\n
  578. \r\n
  579. \r\n //初始条件: 图G存在,v和图G中顶点有相同特征   \r\n
  580. \r\n
  581. \r\n //操作结果: 在图G中增添新顶点v(不增添与顶点相关的弧,留待InsertArc()去做)   \r\n
  582. \r\n
  583. \r\n void InsertVex(MGraph *G, VertexType v) {   \r\n
  584. \r\n
  585. \r\n     int i;  \r\n
  586. \r\n
  587. \r\n     strcpy((*G).vexs[(*G).vexnum], v); //构造新顶点向量  \r\n
  588. \r\n
  589. \r\n     for (i=0; i<=(*G).vexnum; i++) {  \r\n
  590. \r\n
  591. \r\n         if ((*G).kind%2) //网  \r\n
  592. \r\n
  593. \r\n         {  \r\n
  594. \r\n
  595. \r\n             (*G).arcs[(*G).vexnum][i].adj=INFINITY; //初始化该行邻接矩阵的值(无边或弧)   \r\n
  596. \r\n
  597. \r\n             (*G).arcs[i][(*G).vexnum].adj=INFINITY; //初始化该列邻接矩阵的值(无边或弧)  \r\n
  598. \r\n
  599. \r\n         } else //图  \r\n
  600. \r\n
  601. \r\n         {  \r\n
  602. \r\n
  603. \r\n             (*G).arcs[(*G).vexnum][i].adj=0; //初始化该行邻接矩阵的值(无边或弧)   \r\n
  604. \r\n
  605. \r\n             (*G).arcs[i][(*G).vexnum].adj=0; //初始化该列邻接矩阵的值(无边或弧)   \r\n
  606. \r\n
  607. \r\n         }  \r\n
  608. \r\n
  609. \r\n         (*G).arcs[(*G).vexnum][i].info=NULL; //初始化相关信息指针  \r\n
  610. \r\n
  611. \r\n         (*G).arcs[i][(*G).vexnum].info=NULL;  \r\n
  612. \r\n
  613. \r\n     }  \r\n
  614. \r\n
  615. \r\n     (*G).vexnum+=1; //图G的顶点数加1  \r\n
  616. \r\n
  617. \r\n }  \r\n
  618. \r\n
  619. \r\n   \r\n
  620. \r\n
  621. \r\n //初始条件: 图G存在,v是G中某个顶点。  \r\n
  622. \r\n
  623. \r\n //操作结果: 删除G中顶点v及其相关的弧   \r\n
  624. \r\n
  625. \r\n Status DeleteVex(MGraph *G, VertexType v) { int i, j, k;  \r\n
  626. \r\n
  627. \r\n VRType m=0;  \r\n
  628. \r\n
  629. \r\n k=LocateVex(*G, v); //k为待删除顶点v的序号  \r\n
  630. \r\n
  631. \r\n if (k<0) //v不是图G的顶点  \r\n
  632. \r\n
  633. \r\n     return ERROR;  \r\n
  634. \r\n
  635. \r\n if ((*G).kind==DN||(*G).kind==UDN) //网  \r\n
  636. \r\n
  637. \r\n     m=INFINITY;  \r\n
  638. \r\n
  639. \r\n for (j=0; j<(*G).vexnum; j++)  \r\n
  640. \r\n
  641. \r\n     //有入弧或边  \r\n
  642. \r\n
  643. \r\n     if ((*G).arcs[j][k].adj!=m)  {  \r\n
  644. \r\n
  645. \r\n         if ((*G).arcs[j][k].info) //有相关信息   \r\n
  646. \r\n
  647. \r\n             free((*G).arcs[j][k].info); //释放相关信息   \r\n
  648. \r\n
  649. \r\n         (*G).arcnum--; // 修改弧数  \r\n
  650. \r\n
  651. \r\n     }  \r\n
  652. \r\n
  653. \r\n     if ((*G).kind==DG||(*G).kind==DN) //有向  \r\n
  654. \r\n
  655. \r\n         for (j=0; j<(*G).vexnum; j++)  \r\n
  656. \r\n
  657. \r\n             //有出弧  \r\n
  658. \r\n
  659. \r\n             if ((*G).arcs[k][j].adj!=m)  {  \r\n
  660. \r\n
  661. \r\n                 if ((*G).arcs[k][j].info) //有相关信息  \r\n
  662. \r\n
  663. \r\n                     free((*G).arcs[k][j].info); // 释放相关信息  \r\n
  664. \r\n
  665. \r\n                 (*G).arcnum--; //修改弧数   \r\n
  666. \r\n
  667. \r\n             }  \r\n
  668. \r\n
  669. \r\n             for (j=k+1; j<(*G).vexnum; j++)  \r\n
  670. \r\n
  671. \r\n                 //序号k后面的顶点向量依次前移  \r\n
  672. \r\n
  673. \r\n                 strcpy((*G).vexs[j-1], (*G).vexs[j]);  \r\n
  674. \r\n
  675. \r\n             for (i=0; i<(*G).vexnum; i++)  \r\n
  676. \r\n
  677. \r\n                 for (j=k+1; j<(*G).vexnum; j++)  \r\n
  678. \r\n
  679. \r\n                     (*G).arcs[i][j-1]=(*G).arcs[i][j]; // 移动待删除顶点之后的矩阵元素   \r\n
  680. \r\n
  681. \r\n             for (i=0; i<(*G).vexnum; i++)  \r\n
  682. \r\n
  683. \r\n                 for (j=k+1; j<(*G).vexnum; j++)  \r\n
  684. \r\n
  685. \r\n                     (*G).arcs[j-1][i]=(*G).arcs[j][i]; // 移动待删除顶点之下的矩阵元素   \r\n
  686. \r\n
  687. \r\n             (*G).vexnum--; //更新图的顶点数  \r\n
  688. \r\n
  689. \r\n             return OK;  \r\n
  690. \r\n
  691. \r\n }  \r\n
  692. \r\n
  693. \r\n   \r\n
  694. \r\n
  695. \r\n //初始条件: 图G存在,v和W是G中两个顶点  \r\n
  696. \r\n
  697. \r\n //操作结果: 在G中增添弧<v,w>,若G是无向的,则还增添对称弧<w,v>   \r\n
  698. \r\n
  699. \r\n Status InsertArc(MGraph *G, VertexType v, VertexType w) {   \r\n
  700. \r\n
  701. \r\n     int i, l, v1, w1;  \r\n
  702. \r\n
  703. \r\n     char *info, s[MAX_INFO];  \r\n
  704. \r\n
  705. \r\n     v1=LocateVex(*G, v); //尾  \r\n
  706. \r\n
  707. \r\n     w1=LocateVex(*G, w); //头  \r\n
  708. \r\n
  709. \r\n     if (v1<0||w1<0)  \r\n
  710. \r\n
  711. \r\n         return ERROR;  \r\n
  712. \r\n
  713. \r\n     (*G).arcnum++; //弧或边数加1  \r\n
  714. \r\n
  715. \r\n     if ((*G).kind%2) //网   \r\n
  716. \r\n
  717. \r\n     {  \r\n
  718. \r\n
  719. \r\n         printf(\"请输入此弧或边的权值: \");  \r\n
  720. \r\n
  721. \r\n         scanf(\"%d\", &(*G).arcs[v1][w1].adj);  \r\n
  722. \r\n
  723. \r\n     } else  \r\n
  724. \r\n
  725. \r\n         //图  \r\n
  726. \r\n
  727. \r\n         (*G).arcs[v1][w1].adj=1;  \r\n
  728. \r\n
  729. \r\n     printf(\"是否有该弧或边的相关信息(0:无 1:有): \");  \r\n
  730. \r\n
  731. \r\n     scanf(\"%d%*c\", &i);  \r\n
  732. \r\n
  733. \r\n     if (i) {  \r\n
  734. \r\n
  735. \r\n         printf(\"请输入该弧或边的相关信息(<%d个字符):\", MAX_INFO);  \r\n
  736. \r\n
  737. \r\n         gets(s);  \r\n
  738. \r\n
  739. \r\n         l=strlen(s);  \r\n
  740. \r\n
  741. \r\n         if (l) {  \r\n
  742. \r\n
  743. \r\n             info=(char*)malloc((l+1)*sizeof(char));  \r\n
  744. \r\n
  745. \r\n             strcpy(info, s);  \r\n
  746. \r\n
  747. \r\n             (*G).arcs[v1][w1].info=info;  \r\n
  748. \r\n
  749. \r\n         }  \r\n
  750. \r\n
  751. \r\n     }  \r\n
  752. \r\n
  753. \r\n     //无向  \r\n
  754. \r\n
  755. \r\n     if ((*G).kind>1) {  \r\n
  756. \r\n
  757. \r\n         (*G).arcs[w1][v1].adj=(*G).arcs[v1][w1].adj;  \r\n
  758. \r\n
  759. \r\n         (*G).arcs[w1][v1].info=(*G).arcs[v1][w1].info; //指向同一个相关信息  \r\n
  760. \r\n
  761. \r\n     }  \r\n
  762. \r\n
  763. \r\n     return OK;  \r\n
  764. \r\n
  765. \r\n }  \r\n
  766. \r\n
  767. \r\n   \r\n
  768. \r\n
  769. \r\n //初始条件: 图G存在,v和w是G中两个顶点  \r\n
  770. \r\n
  771. \r\n //操作结果: 在G中删除弧<v,w>,若G是无向的,则还删除对称弧<w,v>   \r\n
  772. \r\n
  773. \r\n Status DeleteArc(MGraph *G, VertexType v, VertexType w) {   \r\n
  774. \r\n
  775. \r\n     int v1, w1;  \r\n
  776. \r\n
  777. \r\n     v1=LocateVex(*G, v); //尾  \r\n
  778. \r\n
  779. \r\n     w1=LocateVex(*G, w); //头   \r\n
  780. \r\n
  781. \r\n     if (v1<0||w1<0) //v1、w1的值不合法  \r\n
  782. \r\n
  783. \r\n         return ERROR;  \r\n
  784. \r\n
  785. \r\n     if ((*G).kind%2==0) //图   \r\n
  786. \r\n
  787. \r\n         (*G).arcs[v1][w1].adj=0;  \r\n
  788. \r\n
  789. \r\n     else  \r\n
  790. \r\n
  791. \r\n         //网  \r\n
  792. \r\n
  793. \r\n         (*G).arcs[v1][w1].adj=INFINITY;  \r\n
  794. \r\n
  795. \r\n     //有其它信息  \r\n
  796. \r\n
  797. \r\n     if ((*G).arcs[v1][w1].info) {  \r\n
  798. \r\n
  799. \r\n         free((*G).arcs[v1][w1].info);  \r\n
  800. \r\n
  801. \r\n         (*G).arcs[v1][w1].info=NULL;  \r\n
  802. \r\n
  803. \r\n     }  \r\n
  804. \r\n
  805. \r\n     //无向,删除对称弧<w,v>   \r\n
  806. \r\n
  807. \r\n     if ((*G).kind>=2){  \r\n
  808. \r\n
  809. \r\n         (*G).arcs[w1][v1].adj=(*G).arcs[v1][w1].adj;  \r\n
  810. \r\n
  811. \r\n         (*G).arcs[w1][v1].info=NULL;  \r\n
  812. \r\n
  813. \r\n     }  \r\n
  814. \r\n
  815. \r\n     (*G).arcnum--;  \r\n
  816. \r\n
  817. \r\n     return OK;  \r\n
  818. \r\n
  819. \r\n }  \r\n
  820. \r\n
  821. \r\n   \r\n
  822. \r\n
  823. \r\n Boolean visited[MAX_VERTEX_NUM]; //访问标志数组(全局变量)  \r\n
  824. \r\n
  825. \r\n Status(*VisitFunc)(VertexType); //函数变量  \r\n
  826. \r\n
  827. \r\n   \r\n
  828. \r\n
  829. \r\n //从第v个顶点出发递归地深度优先遍历图G。算法7.5   \r\n
  830. \r\n
  831. \r\n void DFS(MGraph G, int v) {  \r\n
  832. \r\n
  833. \r\n     VertexType w1, v1;  \r\n
  834. \r\n
  835. \r\n     int w;  \r\n
  836. \r\n
  837. \r\n     visited[v]=TRUE; //设置访问标志为TRUE(已访问)   \r\n
  838. \r\n
  839. \r\n     VisitFunc(G.vexs[v]); //访问第v个顶点  \r\n
  840. \r\n
  841. \r\n     w=FirstAdjVex(G, v1);  \r\n
  842. \r\n
  843. \r\n     strcpy(v1, *GetVex(G, v));  \r\n
  844. \r\n
  845. \r\n     strcpy(w1, *GetVex(G, w));  \r\n
  846. \r\n
  847. \r\n     for (; w>=0; w=NextAdjVex(G, v1, w1)) {  \r\n
  848. \r\n
  849. \r\n         strcpy(w1, *GetVex(G, w));  \r\n
  850. \r\n
  851. \r\n         if (!visited[w])  \r\n
  852. \r\n
  853. \r\n             DFS(G, w);  \r\n
  854. \r\n
  855. \r\n     }//对v的尚未访问的序号为w的邻接顶点递归调用DFS   \r\n
  856. \r\n
  857. \r\n }  \r\n
  858. \r\n
  859. \r\n   \r\n
  860. \r\n
  861. \r\n //初始条件: 图G存在,Visit是顶点的应用函数。算法7.4   \r\n
  862. \r\n
  863. \r\n //操作结果: 从第1个顶点起,深度优先遍历图G,并对每个顶点调用函数Visit, 一次且仅一次。一旦Visit()失败,则操作失败   \r\n
  864. \r\n
  865. \r\n void DFSTraverse(MGraph G, Status (*Visit)(VertexType)) {   \r\n
  866. \r\n
  867. \r\n     printf(\"n************************************************************************n\");  \r\n
  868. \r\n
  869. \r\n     printf(\"*深度优先遍历                                                          *n\");  \r\n
  870. \r\n
  871. \r\n     printf(\"************************************************************************n\");  \r\n
  872. \r\n
  873. \r\n   \r\n
  874. \r\n
  875. \r\n     int v;  \r\n
  876. \r\n
  877. \r\n     VisitFunc=Visit; //使用全局变量VisitFunc,使DFS不必设函数指针参数  \r\n
  878. \r\n
  879. \r\n     for (v=0; v<G.vexnum; v++)  \r\n
  880. \r\n
  881. \r\n         visited[v]=FALSE; //访问标志数组初始化(未被访问)  \r\n
  882. \r\n
  883. \r\n     for (v=0; v<G.vexnum; v++) {  \r\n
  884. \r\n
  885. \r\n         if (!visited[v]) {  \r\n
  886. \r\n
  887. \r\n             DFS(G, v); // 对尚未访问的顶点调用DFS   \r\n
  888. \r\n
  889. \r\n         }  \r\n
  890. \r\n
  891. \r\n     }  \r\n
  892. \r\n
  893. \r\n     printf(\"n\");  \r\n
  894. \r\n
  895. \r\n }  \r\n
  896. \r\n
  897. \r\n   \r\n
  898. \r\n
  899. \r\n typedef VRType QElemType; //队列类型   \r\n
  900. \r\n
  901. \r\n #include \"LinkQueue.h\" //BFSTraverse()用  \r\n
  902. \r\n
  903. \r\n   \r\n
  904. \r\n
  905. \r\n // 初始条件: 图G存在,Visit是顶点的应用函数。算法7.6   \r\n
  906. \r\n
  907. \r\n //操作结果: 从第1个顶点起,按广度优先非递归遍历图G,并对每个顶点调用函数,Visit一次且仅一次。  \r\n
  908. \r\n
  909. \r\n //一旦Visit()失败,则操作失败。  \r\n
  910. \r\n
  911. \r\n //使用辅助队列Q和访问标志数组visited   \r\n
  912. \r\n
  913. \r\n void BFSTraverse(MGraph G, Status(*Visit)(VertexType)) {   \r\n
  914. \r\n
  915. \r\n     printf(\"n************************************************************************n\");  \r\n
  916. \r\n
  917. \r\n     printf(\"*广度优先遍历                                                          *n\");  \r\n
  918. \r\n
  919. \r\n     printf(\"************************************************************************n\");  \r\n
  920. \r\n
  921. \r\n   \r\n
  922. \r\n
  923. \r\n     int v, u, w;  \r\n
  924. \r\n
  925. \r\n     VertexType w1, u1;  \r\n
  926. \r\n
  927. \r\n     LinkQueue Q;  \r\n
  928. \r\n
  929. \r\n     for (v=0; v<G.vexnum; v++)  \r\n
  930. \r\n
  931. \r\n         visited[v]=FALSE; //置初值  \r\n
  932. \r\n
  933. \r\n     InitQueue(&Q); //置空的辅助队列Q  \r\n
  934. \r\n
  935. \r\n     for (v=0; v<G.vexnum; v++)  \r\n
  936. \r\n
  937. \r\n         //v尚未访问  \r\n
  938. \r\n
  939. \r\n         if (!visited[v]){  \r\n
  940. \r\n
  941. \r\n             visited[v]=TRUE; //设置访问标志为TRUE(已访问)  \r\n
  942. \r\n
  943. \r\n             Visit(G.vexs[v]);  \r\n
  944. \r\n
  945. \r\n             EnQueue(&Q, v); //v入队列  \r\n
  946. \r\n
  947. \r\n             //队列不空  \r\n
  948. \r\n
  949. \r\n             while (!QueueEmpty(Q)) {  \r\n
  950. \r\n
  951. \r\n                 DeQueue(&Q, &u); //队头元素出队并置为u  \r\n
  952. \r\n
  953. \r\n                 strcpy(u1, *GetVex(G, u));  \r\n
  954. \r\n
  955. \r\n                 for (w=FirstAdjVex(G, u1); w>=0; w=NextAdjVex(G, u1, strcpy(w1,  \r\n
  956. \r\n
  957. \r\n                     *GetVex(G, w))))  \r\n
  958. \r\n
  959. \r\n                     //w为u的尚未访问的邻接顶点的序号   \r\n
  960. \r\n
  961. \r\n                     if (!visited[w]) {  \r\n
  962. \r\n
  963. \r\n                         visited[w]=TRUE;  \r\n
  964. \r\n
  965. \r\n                         Visit(G.vexs[w]);  \r\n
  966. \r\n
  967. \r\n                         EnQueue(&Q, w);  \r\n
  968. \r\n
  969. \r\n                     }  \r\n
  970. \r\n
  971. \r\n             }  \r\n
  972. \r\n
  973. \r\n         }  \r\n
  974. \r\n
  975. \r\n         printf(\"n\");  \r\n
  976. \r\n
  977. \r\n }  \r\n
  978. \r\n
  979. \r\n   \r\n
  980. \r\n
  981. \r\n //输出邻接矩阵G   \r\n
  982. \r\n
  983. \r\n void Display(MGraph G) {  \r\n
  984. \r\n
  985. \r\n     int i, j;  \r\n
  986. \r\n
  987. \r\n     char s[7], s1[3];  \r\n
  988. \r\n
  989. \r\n     switch (G.kind) {  \r\n
  990. \r\n
  991. \r\n     case DG:  \r\n
  992. \r\n
  993. \r\n         strcpy(s, \"有向图 \");  \r\n
  994. \r\n
  995. \r\n         strcpy(s1, \"弧 \");  \r\n
  996. \r\n
  997. \r\n         break;  \r\n
  998. \r\n
  999. \r\n     case DN:  \r\n
  1000. \r\n
  1001. \r\n         strcpy(s, \"有向网 \");  \r\n
  1002. \r\n
  1003. \r\n         strcpy(s1, \"弧 \");  \r\n
  1004. \r\n
  1005. \r\n         break;  \r\n
  1006. \r\n
  1007. \r\n     case UDG:  \r\n
  1008. \r\n
  1009. \r\n         strcpy(s, \"无向图 \");  \r\n
  1010. \r\n
  1011. \r\n         strcpy(s1, \"边 \");  \r\n
  1012. \r\n
  1013. \r\n         break;  \r\n
  1014. \r\n
  1015. \r\n     case UDN:  \r\n
  1016. \r\n
  1017. \r\n         strcpy(s, \"无向网 \");  \r\n
  1018. \r\n
  1019. \r\n         strcpy(s1, \"边 \");  \r\n
  1020. \r\n
  1021. \r\n     }  \r\n
  1022. \r\n
  1023. \r\n   \r\n
  1024. \r\n
  1025. \r\n     printf(\"n************************************************************************n\");  \r\n
  1026. \r\n
  1027. \r\n     printf(\"*输出%s的邻接矩阵                                                  *n\",s);  \r\n
  1028. \r\n
  1029. \r\n     printf(\"************************************************************************n\");  \r\n
  1030. \r\n
  1031. \r\n   \r\n
  1032. \r\n
  1033. \r\n   \r\n
  1034. \r\n
  1035. \r\n     printf(\"%d个顶点%d条%s的%sn\", G.vexnum, G.arcnum, s1, s);  \r\n
  1036. \r\n
  1037. \r\n     for (i=0; i<G.vexnum; ++i)  \r\n
  1038. \r\n
  1039. \r\n         //输出G.vexs   \r\n
  1040. \r\n
  1041. \r\n         printf(\"G.vexs[%d]=%sn\", i, G.vexs[i]);  \r\n
  1042. \r\n
  1043. \r\n     printf(\"G.arcs.adj:n\"); // 输出G.arcs.adj   \r\n
  1044. \r\n
  1045. \r\n     for (i=0; i<G.vexnum; i++) {  \r\n
  1046. \r\n
  1047. \r\n         for (j=0; j<G.vexnum; j++)  \r\n
  1048. \r\n
  1049. \r\n             printf(\"%6d\", G.arcs[i][j].adj);  \r\n
  1050. \r\n
  1051. \r\n         printf(\"n\");  \r\n
  1052. \r\n
  1053. \r\n     }  \r\n
  1054. \r\n
  1055. \r\n     printf(\"G.arcs.info:n\"); //输出G.arcs.info   \r\n
  1056. \r\n
  1057. \r\n     printf(\"顶点1(弧尾) 顶点2(弧头) 该%s信息:n\", s1);  \r\n
  1058. \r\n
  1059. \r\n     if (G.kind<2) //有向   \r\n
  1060. \r\n
  1061. \r\n         for (i=0; i<G.vexnum; i++)  \r\n
  1062. \r\n
  1063. \r\n             for (j=0; j<G.vexnum; j++) {  \r\n
  1064. \r\n
  1065. \r\n                 if (G.arcs[i][j].info)  \r\n
  1066. \r\n
  1067. \r\n                     printf(\"%5s %11s     %sn\", G.vexs[i], G.vexs[j],  \r\n
  1068. \r\n
  1069. \r\n                     G.arcs[i][j].info);  \r\n
  1070. \r\n
  1071. \r\n             }  \r\n
  1072. \r\n
  1073. \r\n             //无向  \r\n
  1074. \r\n
  1075. \r\n     else {  \r\n
  1076. \r\n
  1077. \r\n         for (i=0; i<G.vexnum; i++)  \r\n
  1078. \r\n
  1079. \r\n             for (j=i+1; j<G.vexnum; j++)  \r\n
  1080. \r\n
  1081. \r\n                 if (G.arcs[i][j].info)  \r\n
  1082. \r\n
  1083. \r\n                     printf(\"%5s %11s     %sn\", G.vexs[i], G.vexs[j],  \r\n
  1084. \r\n
  1085. \r\n                     G.arcs[i][j].info);  \r\n
  1086. \r\n
  1087. \r\n     }  \r\n
  1088. \r\n
  1089. \r\n   \r\n
  1090. \r\n
  1091. \r\n }  \r\n
  1092. \r\n
\r\n
\r\n
\r\n
\r\n

\r\n
\r\n

\r\n
\r\n

\r\n Main.cpp\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n /************************************************************************/  \r\n
  2. \r\n
  3. \r\n /*Main.cpp                                                              */  \r\n
  4. \r\n
  5. \r\n /* 实现算法7.9的程序                                                    */  \r\n
  6. \r\n
  7. \r\n /************************************************************************/  \r\n
  8. \r\n
  9. \r\n #include \"Basic.h\"  \r\n
  10. \r\n
  11. \r\n typedef int VRType;  \r\n
  12. \r\n
  13. \r\n typedef char InfoType;  \r\n
  14. \r\n
  15. \r\n #define MAX_NAME 3 //顶点字符串的最大长度+1   \r\n
  16. \r\n
  17. \r\n #define MAX_INFO 20 //相关信息字符串的最大长度+1   \r\n
  18. \r\n
  19. \r\n typedef char VertexType[MAX_NAME];  \r\n
  20. \r\n
  21. \r\n #include \"MGraph.h\"  \r\n
  22. \r\n
  23. \r\n   \r\n
  24. \r\n
  25. \r\n //记录从顶点集U到V-U的代价最小的边的辅助数组定义  \r\n
  26. \r\n
  27. \r\n typedef struct{   \r\n
  28. \r\n
  29. \r\n     VertexType adjvex;  \r\n
  30. \r\n
  31. \r\n     VRType lowcost;  \r\n
  32. \r\n
  33. \r\n }minside[MAX_VERTEX_NUM];  \r\n
  34. \r\n
  35. \r\n   \r\n
  36. \r\n
  37. \r\n //求closedge.lowcost的最小正值   \r\n
  38. \r\n
  39. \r\n int minimum(minside closeedge,MGraph G){   \r\n
  40. \r\n
  41. \r\n     int i=0,j,k,min;  \r\n
  42. \r\n
  43. \r\n     while(!closeedge[i].lowcost)  \r\n
  44. \r\n
  45. \r\n         i++;  \r\n
  46. \r\n
  47. \r\n     min=closeedge[i].lowcost; //第一个不为0的值   \r\n
  48. \r\n
  49. \r\n     k=i;  \r\n
  50. \r\n
  51. \r\n     for(j=i+1;j<G.vexnum;j++)  \r\n
  52. \r\n
  53. \r\n         if(closeedge[j].lowcost>0)  \r\n
  54. \r\n
  55. \r\n             if(min>closeedge[j].lowcost){  \r\n
  56. \r\n
  57. \r\n                 min=closeedge[j].lowcost;  \r\n
  58. \r\n
  59. \r\n                 k=j;  \r\n
  60. \r\n
  61. \r\n             }  \r\n
  62. \r\n
  63. \r\n             return k;  \r\n
  64. \r\n
  65. \r\n }  \r\n
  66. \r\n
  67. \r\n   \r\n
  68. \r\n
  69. \r\n //用普里姆算法从第u个顶点出发构造网G的最小生成树T,输出T的各条边 算法7.9   \r\n
  70. \r\n
  71. \r\n void MiniSpanTree_PRIM(MGraph G,VertexType u){   \r\n
  72. \r\n
  73. \r\n     printf(\"n************************************************************************n\");  \r\n
  74. \r\n
  75. \r\n     printf(\"*最小生成树的Prim算法                                                  *n\");  \r\n
  76. \r\n
  77. \r\n     printf(\"************************************************************************n\");  \r\n
  78. \r\n
  79. \r\n   \r\n
  80. \r\n
  81. \r\n     int i,j,k;  \r\n
  82. \r\n
  83. \r\n     minside closedge;  \r\n
  84. \r\n
  85. \r\n     k=LocateVex(G,u);  \r\n
  86. \r\n
  87. \r\n     for(j=0;j<G.vexnum;++j) {//辅助数组初始化   \r\n
  88. \r\n
  89. \r\n         if(j!=k){  \r\n
  90. \r\n
  91. \r\n             strcpy(closedge[j].adjvex,u);  \r\n
  92. \r\n
  93. \r\n             closedge[j].lowcost=G.arcs[k][j].adj;  \r\n
  94. \r\n
  95. \r\n         }  \r\n
  96. \r\n
  97. \r\n     }  \r\n
  98. \r\n
  99. \r\n     closedge[k].lowcost=0; //初始,U={u}   \r\n
  100. \r\n
  101. \r\n     printf(\"最小代价生成树的各条边为:n\");  \r\n
  102. \r\n
  103. \r\n     for(i=1;i<G.vexnum;++i){ //选择其余G.vexnum-1个顶点   \r\n
  104. \r\n
  105. \r\n         k=minimum(closedge,G); //求出T的下一个结点:第K顶点   \r\n
  106. \r\n
  107. \r\n         printf(\"(%s-%s)n\",closedge[k].adjvex,G.vexs[k]); //输出生成树的边   \r\n
  108. \r\n
  109. \r\n         closedge[k].lowcost=0; //第K顶点并入U集   \r\n
  110. \r\n
  111. \r\n         for(j=0;j<G.vexnum;++j)  \r\n
  112. \r\n
  113. \r\n             if(G.arcs[k][j].adj<closedge[j].lowcost){ //新顶点并入U集后重新选择最小边   \r\n
  114. \r\n
  115. \r\n                 strcpy(closedge[j].adjvex,G.vexs[k]);  \r\n
  116. \r\n
  117. \r\n                 closedge[j].lowcost=G.arcs[k][j].adj;  \r\n
  118. \r\n
  119. \r\n             }  \r\n
  120. \r\n
  121. \r\n     }  \r\n
  122. \r\n
  123. \r\n }  \r\n
  124. \r\n
  125. \r\n   \r\n
  126. \r\n
  127. \r\n int main(){  \r\n
  128. \r\n
  129. \r\n     MGraph G;  \r\n
  130. \r\n
  131. \r\n     CreateUDN(&G);  \r\n
  132. \r\n
  133. \r\n     MiniSpanTree_PRIM(G,\"V1\");  \r\n
  134. \r\n
  135. \r\n       \r\n
  136. \r\n
  137. \r\n     system(\"pause\");  \r\n
  138. \r\n
  139. \r\n     return 0;  \r\n
  140. \r\n
  141. \r\n }  \r\n
  142. \r\n
\r\n
\r\n
\r\n
\r\n

\r\n
\r\n

\r\n
\r\n

\r\n 测试数据\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n 输入:  \r\n
  2. \r\n
  3. \r\n 6 10 0  \r\n
  4. \r\n
  5. \r\n V1  \r\n
  6. \r\n
  7. \r\n V2  \r\n
  8. \r\n
  9. \r\n V3  \r\n
  10. \r\n
  11. \r\n V4  \r\n
  12. \r\n
  13. \r\n V5  \r\n
  14. \r\n
  15. \r\n V6  \r\n
  16. \r\n
  17. \r\n V1 V2 6  \r\n
  18. \r\n
  19. \r\n V1 V3 1  \r\n
  20. \r\n
  21. \r\n V1 V4 5  \r\n
  22. \r\n
  23. \r\n V2 V3 5  \r\n
  24. \r\n
  25. \r\n V2 V5 3  \r\n
  26. \r\n
  27. \r\n V3 V4 5  \r\n
  28. \r\n
  29. \r\n V3 V5 6  \r\n
  30. \r\n
  31. \r\n V4 V6 2  \r\n
  32. \r\n
  33. \r\n V5 V6 6  \r\n
  34. \r\n
  35. \r\n V3 V6 4  \r\n
  36. \r\n
  37. \r\n   \r\n
  38. \r\n
  39. \r\n 输出:  \r\n
  40. \r\n
  41. \r\n 最小代价生成树的各条边为:  \r\n
  42. \r\n
  43. \r\n (V1-V3)  \r\n
  44. \r\n
  45. \r\n (V3-V6)  \r\n
  46. \r\n
  47. \r\n (V6-V4)  \r\n
  48. \r\n
  49. \r\n (V3-V2)  \r\n
  50. \r\n
  51. \r\n (V2-V5)  \r\n
  52. \r\n
\r\n
\r\n
\r\n
\r\n

\r\n 运行结果\r\n

\r\n

\r\n \"\"\r\n

\r\n

\r\n
\r\n

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2539, 'android-hc-post-get', 'Android利用HttpClient和Post与Get请求与服务器交互', '2013-10-31 06:00:00', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

代码如下:

  1. import org.apache.http.HttpResponse;   
  2. import org.apache.http.HttpStatus;   
  3. import org.apache.http.NameValuePair;   
  4. import org.apache.http.client.HttpClient;   
  5. import org.apache.http.client.entity.UrlEncodedFormEntity;   
  6. import org.apache.http.client.methods.HttpGet;   
  7. import org.apache.http.client.methods.HttpPost;   
  8. import org.apache.http.impl.client.DefaultHttpClient;   
  9. import org.apache.http.protocol.HTTP;   
  10. import org.apache.http.util.EntityUtils;   
  11. import java.io.BufferedReader;   
  12. import java.io.InputStreamReader;   
  13. import java.util.List;   
  14. public class HttpUtils {   
  15.     /**   
  16.      *   
  17.      * @param url地址   
  18.      * @return 返回网页内容   
  19.      * @throws Exception   
  20.      */   
  21.     public static String get(String url) throws Exception {   
  22.         HttpClient client = new DefaultHttpClient();   
  23.         HttpGet get = new HttpGet(url);   
  24.         HttpResponse response = client.execute(get);   
  25.         BufferedReader reader = new BufferedReader(new InputStreamReader(   
  26.                     response.getEntity().getContent()));   
  27.         String resStr = "";   
  28.         for (String s = reader.readLine(); s != null; s = reader.readLine()) {   
  29.             resStr += s;   
  30.         }   
  31.         return resStr;   
  32.     }   
  33.     /**   
  34.      *   
  35.      * @param url 网页地址   
  36.      * @param params 参数   
  37.      * @return 返回网页内容   
  38.      * @throws Exception   
  39.      */   
  40.     public static String post(String url, List<NameValuePair> params)   
  41.         throws Exception {   
  42.         String response = null;   
  43.         HttpClient httpclient = new DefaultHttpClient();   
  44.         // 创建HttpPost对象   
  45.         HttpPost httppost = new HttpPost(url);   
  46.         try {   
  47.             // 设置httpPost请求参数,设置字符集   
  48.             httppost.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));   
  49.             // 使用execute方法发送HTTP Post请求,并返回HttpResponse对象   
  50.             HttpResponse httpResponse = httpclient.execute(httppost);   
  51.             int statusCode = httpResponse.getStatusLine().getStatusCode();   
  52.             if (statusCode == HttpStatus.SC_OK) {   
  53.                 // 获得返回结果   
  54.                 response = EntityUtils.toString(httpResponse.getEntity());   
  55.             } else {   
  56.                 response = "请求错误,返回码:" + statusCode;   
  57.             }   
  58.         } catch (Exception e) {   
  59.             e.getMessage();   
  60.         }   
  61.         return response;   
  62.     }   
  63. }   

测试:

  1. String data;   
  2.    
  3. Gett方式   
  4. data =   
  5. HttpUtils.get("http://10.0.2.2:8080/Auction/LoginAction.action?username="+   
  6. username + "&password=" + password + "");   
  7.    
  8. Post方式   
  9.    List<NameValuePair> params = new ArrayList<NameValuePair>();   
  10.    params.add(new BasicNameValuePair("username", username));   
  11.    params.add(new BasicNameValuePair("password", password));   
  12.    data = HttpUtils.post(   
  13.    "http://10.0.2.2:8080/Auction/LoginAction.action",   
  14.    params);   
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2540, 'vx', 'Visual.Assist.X.V10.7.1940下载及破解方法', '2013-10-30 06:00:00', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

 软件截图: 

暂无

 安全认证:

 \"clip_image001\"360通过 \"clip_image002[8]\"金山通过\"clip_image003[8]\"瑞星通过\"clip_image004[8]\"卡巴通过 \"clip_image005[8]\"小红伞通过

 \"clip_image006[8]\"NOD通过\"clip_image007[8]\"无插件\"no\"无病毒\"clip_image008[8]\"win7兼容 \"clip_image009[8]\"新价值网认证

软件大小:30.28MB(精简版) 485.73MB(完整版)

下载次数:44

软件授权:破解软件

软件语言:英文版

开 发 商:本网收集

评价等级:

发布时间:2012-10-17 19:47:56

更新时间:2013-07-02 19:47:56

软件版本:V6.0

应用平台:Win7/Vista/Win2003/WinXP/Win2000/

软件介绍:超强悍的代码提示插件。

破解方法:

找到V\r\nA_X.dll,将VA_X.dll替换。

      2010的Visual Assist X是使用Extension的方式安装的,所以你得到这个路径去破解,就是把破解补丁拷贝到这个路径下,直接运行补丁程序或者覆盖VA_X.dll 即可:

       Windows7路径

       C:UsersAdministratorAppDataLocalMicrosoftVisualStudio10.0ExtensionsWhole Tomato SoftwareVisual Assist X10.7.1940.0

        XP的路径:

C:Documents and SettingsAdministratorLocal SettingsApplication DataMicrosoftVisualStudio10.0ExtensionsWhole Tomato SoftwareVisual Assist X10.7.1940.0

      注意:将Administrator换成你的用户名。

下载地址:

下载地址一:

\"bdyun\" 

     

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2541, 'vc6-show-line-number', 'VC6显示行号插件', '2013-10-29 06:00:00', '2019-03-25 21:29:22', '

\r\n 【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】\r\n

\r\n

\r\n  软件截图: \r\n

\r\n

\r\n 暂无\r\n

\r\n

\r\n  安全认证:\r\n

\r\n

\r\n  \"clip_image001\"360通过 \"clip_image002[8]\"金山通过\"clip_image003[8]\"瑞星通过\"clip_image004[8]\"卡巴通过 \"clip_image005[8]\"小红伞通过\r\n

\r\n

\r\n  \"clip_image006[8]\"NOD通过\"clip_image007[8]\"无插件\"no\"无病毒\"clip_image008[8]\"win7兼容 \"clip_image009[8]\"新价值网认证\r\n

\r\n

\r\n 软件大小:159.89KB\r\n

\r\n

\r\n 下载次数:44\r\n

\r\n

\r\n 软件授权:免费软件\r\n

\r\n

\r\n 软件语言:简体中文\r\n

\r\n

\r\n 开 发 商:本站收集\r\n

\r\n

\r\n 评价等级:\r\n

\r\n

\r\n 发布时间:2011-10-17 19:47:56\r\n

\r\n

\r\n 更新时间:2013-07-02 19:47:56\r\n

\r\n

\r\n 软件版本:V6.0\r\n

\r\n

\r\n 应用平台:Win7/Vista/Win2003/WinXP/Win2000/\r\n

\r\n

\r\n 软件介绍:VC6显示行号插件。 \r\n

\r\n

\r\n 使用说明:\r\n

\r\n

\r\n 1. 如果你的VC安装在C盘,请拷贝文件VC6LineNumberAddin.dll到如下目录:\r\n

\r\n

\r\n C:Program FilesMicrosoft Visual StudioCommonMSDev98AddIns\r\n

\r\n

\r\n 2. 注册\r\n

\r\n

\r\n 双击VC6LineNumberAddin.reg进行注册。\r\n

\r\n

\r\n 3. 启用\r\n

\r\n

\r\n 打开vc6,菜单栏:Tools -> customize -> Add-ins and Macro Files\r\n

\r\n

\r\n 选中VC6LineNumber Developer Studio Add-in。\r\n

\r\n

\r\n 下载地址:\r\n

\r\n

\r\n \r\n

\r\n下载地址一: \r\n

\r\n \"bdyun\" \r\n

\r\n

\r\n  \r\n

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2542, 'tc2', 'Turbo C++ 2.0下载', '2013-10-28 06:00:00', '2019-03-26 00:22:02', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

\r\n

 软件截图: 

\r\n

\"tc\"

\r\n

 安全认证:

\r\n

 \"clip_image001\"360通过 \"clip_image002[8]\"金山通过\"clip_image003[8]\"瑞星通过\"clip_image004[8]\"卡巴通过 \"clip_image005[8]\"小红伞通过

\r\n

 \"clip_image006[8]\"NOD通过\"clip_image007[8]\"无插件\"no\"无病毒\"clip_image008[8]\"win7兼容 \"clip_image009[8]\"新价值网认证

\r\n

软件大小:30.28MB

\r\n

下载次数:4

\r\n

软件授权:免费软件

\r\n

软件语言:英文

\r\n

开 发 商:本网收集

\r\n

评价等级:\"\"\"\"\"\"

\r\n

发布时间:2011-10-17 19:47:56

\r\n

更新时间:2013-07-02 19:47:56

\r\n

软件版本:V6.0

\r\n

应用平台:Win7/Vista/Win2003/WinXP/Win2000/

\r\n

软件介绍:  C/C++语言编程工具,小巧实用,是编程和学习C语言的好工具,该版本比2.0版本增加了关键字的突出显示等功能,并且界面更友好了。推荐初学C/C++者使用。

\r\n

温馨提示:小巧但且经典的C语言软件

\r\n

下载地址:

\r\n

 下载地址一:

\r\n

\"bdyun\" 

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2543, 'ssh2-jars', 'ssh2必须jar包集合(Struts2.3.4.1+Spring3.2.3+Hibernate4.1.9最新完美无冲突集成)', '2013-08-27 06:00:00', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

\r\n

 软件截图

\r\n

\"1\" 

\r\n

 安全认证

\r\n

 \"clip_image001_thumb\"360通过 \"clip_image0028_thumb1\"金山通过\"clip_image0038_thumb\"瑞星通过\"clip_image0048_thumb\"卡巴通过 \"clip_image0058_thumb\"小红伞通过

\r\n

 \"clip_image0068_thumb\"NOD通过\"clip_image0078_thumb\"无插件\"no_thumb1\"无病毒\"clip_image0088_thumb\"win7兼容 \"clip_image0098_thumb\"新价值网认证

\r\n

评价等级

\r\n

\"\"\"\"\"\"\"\"

\r\n

发布时间

\r\n

2013-1-17 19:47:56

\r\n

更新时间

\r\n

2013-09-02 19:47:56

\r\n

软件版本

\r\n

V1.0

\r\n

应用平台

\r\n

Win7/Vista/Win2003/WinXP/Win2000/

\r\n

软件介绍

\r\n

ssh2必须jar包集合(Struts2.3.4.1+Spring3.2.3+Hibernate4.1.9最新完美无冲突集成)。

\r\n

温馨提示

\r\n

本插件经笔者亲测可用,欢迎下载

\r\n

下载地址

\r\n

下载地址一

\r\n

[download id=\"7\"]

\r\n

\r\n

入门教程

\r\n

http://www.xinvalue.com/ssh2.html

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2544, 'print-three-num-desc', '输入三个数,然后从大到小输出', '2013-10-26 06:00:00', '2019-03-25 21:29:22', '

\r\n 【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】\r\n

\r\n
\r\n
\r\n
\r\n
    \r\n
  1. \r\n #include <stdio.h>   \r\n
  2. \r\n
  3. \r\n #include <stdlib.h>   \r\n
  4. \r\n
  5. \r\n   \r\n
  6. \r\n
  7. \r\n void Descending(int &a,int &b,int &c){   \r\n
  8. \r\n
  9. \r\n       int temp=0;   \r\n
  10. \r\n
  11. \r\n       if(a<b){   \r\n
  12. \r\n
  13. \r\n           temp=a;a=b;b=temp;//促使a>=b   \r\n
  14. \r\n
  15. \r\n       }   \r\n
  16. \r\n
  17. \r\n       if(b<c){   \r\n
  18. \r\n
  19. \r\n         temp=c;c=b;//促使temp>=c   \r\n
  20. \r\n
  21. \r\n         if(a>=temp) b=temp;   \r\n
  22. \r\n
  23. \r\n         else{   \r\n
  24. \r\n
  25. \r\n         b=a;a=temp;//注意,不能写成a=temp;b=a;   \r\n
  26. \r\n
  27. \r\n         }   \r\n
  28. \r\n
  29. \r\n       }   \r\n
  30. \r\n
  31. \r\n }   \r\n
  32. \r\n
  33. \r\n   \r\n
  34. \r\n
  35. \r\n int main()   \r\n
  36. \r\n
  37. \r\n {   \r\n
  38. \r\n
  39. \r\n     int a,b,c;   \r\n
  40. \r\n
  41. \r\n     scanf(\"%d%d%d\",&a,&b,&c);   \r\n
  42. \r\n
  43. \r\n     Descending(a,b,c);   \r\n
  44. \r\n
  45. \r\n     printf(\"%d %d %dn\",a,b,c);   \r\n
  46. \r\n
  47. \r\n     system(\"pause\");   \r\n
  48. \r\n
  49. \r\n     return 0;   \r\n
  50. \r\n
  51. \r\n \r\n
  52. \r\n
\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2545, 'csharp-vcode-plugin', 'ASP .NET生成验证码的插件,引用即可使用', '2013-09-25 06:00:00', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

使用方法

添加引用。

下载tangyouwei.dll打开Visual Studio 2010,新建一个ASP .NET空Web程序,将tangyouwei.dll右键添加引用。

建立验证码页面。

新建一个Web窗体,命名VatificationCode.aspx,在页面头部添加using;

    在后台VatificationCode.aspx.cs的Page_Load方法中添加如下代码(为了扩展也可以添加ascx用户控件,本文以aspx页面为例):
    [code lang="csharp" ]VerificationCode vc = new VerificationCode();\r\n   string  vcode=vc.GetVarificationCode();\r\n   Session["vCode"] = vcode;\r\n[/code]
    \r\n
\r\n\r\n

调用验证码页面。

\r\n\r\n

新建一个Web窗体,名为Test.aspx,在body的div内写上以下代码:

\r\n\r\n
\r\n
    \r\n
  1. <img id="Image1" src="VarificationCode.aspx" alt="点击刷新验证码"/> 
  2. \r\n
\r\n
\r\n\r\n

效果预览

\r\n\r\n

在Test.aspx右键->在浏览器中查看。

\r\n\r\n

\"1-121112230954524\"\r\n\r\n
此时的页面还有缺陷,因为他不能动态更新,要实现动态更新,只需将Test.aspx加上JS即可,完整的代码:

\r\n\r\n
\r\n
    \r\n
  1. <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Test.aspx.cs" Inherits="TestProject.Test" %> 
  2. \r\n\r\n
  3.  
  4. \r\n\r\n
  5. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
  6. \r\n\r\n
  7.  
  8. \r\n\r\n
  9. <html xmlns="http://www.w3.org/1999/xhtml"> 
  10. \r\n\r\n
  11. <head runat="server"> 
  12. \r\n\r\n
  13.     <title></title> 
  14. \r\n\r\n
  15.       <script  type="text/javascript"> 
  16. \r\n\r\n
  17.                 function RefreshCode() {  
  18. \r\n\r\n
  19.               var randomnum = Math.random();  
  20. \r\n\r\n
  21.               var img1 = document.getElementById("Image1");  
  22. \r\n\r\n
  23.               img1.src = "VarificationCode.aspx?" + randomnum;  
  24. \r\n\r\n
  25.           }  
  26. \r\n\r\n
  27.  
  28. \r\n\r\n
  29.       </script> 
  30. \r\n\r\n
  31. </head> 
  32. \r\n\r\n
  33. <body> 
  34. \r\n\r\n
  35.     <form id="form1" runat="server"> 
  36. \r\n\r\n
  37.     <div> 
  38. \r\n\r\n
  39.  
  40. \r\n\r\n
  41.     <img id="Image1" src="VarificationCode.aspx" alt="点击刷新验证码"  style="cursor: pointer;" onclick="RefreshCode()" /> 
  42. \r\n\r\n
  43.  
  44. \r\n\r\n
  45.     </div> 
  46. \r\n\r\n
  47.     </form> 
  48. \r\n\r\n
  49. </body> 
  50. \r\n\r\n
  51. </html> 
  52. \r\n
\r\n
\r\n\r\n

核心源码改进版如下

\r\n\r\n

使用ashx,并且基于WebService(2013/3/30更新):

\r\n\r\n
\r\n
    \r\n
  1. using System;  
  2. \r\n\r\n
  3. using System.Collections;  
  4. \r\n\r\n
  5. using System.Configuration;  
  6. \r\n\r\n
  7. using System.Data;  
  8. \r\n\r\n
  9. using System.IO;  
  10. \r\n\r\n
  11. using System.Web;  
  12. \r\n\r\n
  13. using System.Web.Security;  
  14. \r\n\r\n
  15. using System.Web.Services;  
  16. \r\n\r\n
  17. using System.Web.UI;  
  18. \r\n\r\n
  19. using System.Web.UI.HtmlControls;  
  20. \r\n\r\n
  21. using System.Web.UI.WebControls;  
  22. \r\n\r\n
  23. using System.Web.UI.WebControls.WebParts;  
  24. \r\n\r\n
  25. using System.Xml.Linq;  
  26. \r\n\r\n
  27. using System.Drawing;  
  28. \r\n\r\n
  29. using System.Drawing.Imaging;  
  30. \r\n\r\n
  31. using System.Web.SessionState;  
  32. \r\n\r\n
  33.  
  34. \r\n\r\n
  35. namespace Tangyouwei  
  36. \r\n\r\n
  37. {  
  38. \r\n\r\n
  39.     /// <summary>  
  40. \r\n\r\n
  41.     ///生成验证码  
  42. \r\n\r\n
  43.     /// </summary>  
  44. \r\n\r\n
  45.     [WebService(Namespace = "http://tempuri.org/")]  
  46. \r\n\r\n
  47.     [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]  
  48. \r\n\r\n
  49.     public class ValidationCode : IHttpHandler,IRequiresSessionState   
  50. \r\n\r\n
  51.     {  
  52. \r\n\r\n
  53.         public void ProcessRequest(HttpContext context)  
  54. \r\n\r\n
  55.         {  
  56. \r\n\r\n
  57.             string checkCode = GenerateCheckCode();  
  58. \r\n\r\n
  59.             if (checkCode == null || checkCode.Trim() == string.Empty)  
  60. \r\n\r\n
  61.                 return;  
  62. \r\n\r\n
  63.             Bitmap myImage = new Bitmap(80, 30); //生成一个位图  
  64. \r\n\r\n
  65.             Graphics graphic = Graphics.FromImage(myImage); //从一个位图生成一个画布  
  66. \r\n\r\n
  67.  
  68. \r\n\r\n
  69.             graphic.Clear(Color.White); //清除图片背景色  
  70. \r\n\r\n
  71.             Random random = new Random(); //生成随机生成器  
  72. \r\n\r\n
  73.  
  74. \r\n\r\n
  75.             //画图片的前景噪音点  
  76. \r\n\r\n
  77.             for (int i = 0; i < 100; i++)  
  78. \r\n\r\n
  79.             {  
  80. \r\n\r\n
  81.                 int x = random.Next(myImage.Width);  
  82. \r\n\r\n
  83.                 int y = random.Next(myImage.Height);  
  84. \r\n\r\n
  85.                 myImage.SetPixel(x, y, Color.FromArgb(random.Next()));  
  86. \r\n\r\n
  87.             }  
  88. \r\n\r\n
  89.  
  90. \r\n\r\n
  91.  
  92. \r\n\r\n
  93.             //画图片的背景噪音线  
  94. \r\n\r\n
  95.             for (int i = 0; i < 2; i++)  
  96. \r\n\r\n
  97.             {  
  98. \r\n\r\n
  99.                 int x1 = random.Next(myImage.Width);  
  100. \r\n\r\n
  101.                 int x2 = random.Next(myImage.Width);  
  102. \r\n\r\n
  103.                 int y1 = random.Next(myImage.Height);  
  104. \r\n\r\n
  105.                 int y2 = random.Next(myImage.Height);  
  106. \r\n\r\n
  107.                 graphic.DrawLine(new Pen(Color.Black), x1, y1, x2, y2);  
  108. \r\n\r\n
  109.             }  
  110. \r\n\r\n
  111.             Font font = new Font("Arial", 15, FontStyle.Bold);  
  112. \r\n\r\n
  113.  
  114. \r\n\r\n
  115.             System.Drawing.Drawing2D.LinearGradientBrush brush =  
  116. \r\n\r\n
  117.                 new System.Drawing.Drawing2D.LinearGradientBrush(  
  118. \r\n\r\n
  119.                     new Rectangle(0, 0, myImage.Width, myImage.Height), Color.Blue, Color.DarkRed, 1.2f, true);  
  120. \r\n\r\n
  121.             graphic.DrawString(checkCode, font, brush, 2, 2);  
  122. \r\n\r\n
  123.  
  124. \r\n\r\n
  125.             //画图片的边框线  
  126. \r\n\r\n
  127.             graphic.DrawRectangle(new Pen(Color.Silver), 0, 0, myImage.Width - 1, myImage.Height - 1);  
  128. \r\n\r\n
  129.             MemoryStream ms = new MemoryStream();  
  130. \r\n\r\n
  131.             myImage.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);  
  132. \r\n\r\n
  133.  
  134. \r\n\r\n
  135.             context.Session["ValicationCode"] =checkCode;       //将验证码保存到了Session中  
  136. \r\n\r\n
  137.             context.Response.ClearContent();  
  138. \r\n\r\n
  139.             context.Response.ContentType = "image/gif";  
  140. \r\n\r\n
  141.             context.Response.BinaryWrite(ms.ToArray());  
  142. \r\n\r\n
  143.         }  
  144. \r\n\r\n
  145.  
  146. \r\n\r\n
  147.  
  148. \r\n\r\n
  149.         /// <summary>  
  150. \r\n\r\n
  151.         /// 动态生成4个随机数或字母  
  152. \r\n\r\n
  153.         /// </summary>  
  154. \r\n\r\n
  155.         /// <returns>返回验证码字符串</returns>  
  156. \r\n\r\n
  157.         private string GenerateCheckCode()  
  158. \r\n\r\n
  159.         {  
  160. \r\n\r\n
  161.             //动态生成4个随机数或字母  
  162. \r\n\r\n
  163.             int number; //定义变量  
  164. \r\n\r\n
  165.             char code;  
  166. \r\n\r\n
  167.             string checkCode = String.Empty; //空字符串,只读  
  168. \r\n\r\n
  169.             Random random = new Random(); //定义随机变量实例  
  170. \r\n\r\n
  171.  
  172. \r\n\r\n
  173.             for (int i = 0; i < 4; i++)  
  174. \r\n\r\n
  175.             {  
  176. \r\n\r\n
  177.                 //利用for循环生成四个随机数或字母  
  178. \r\n\r\n
  179.                 number = random.Next(); //返回一个小于指定的最大值的非负的随机数 next有三个构造函数   
  180. \r\n\r\n
  181.                 if (number%2 == 0)  
  182. \r\n\r\n
  183.                 {  
  184. \r\n\r\n
  185. //产生1个1位数  
  186. \r\n\r\n
  187.                     code = (char) (\'0\' + (char) (number%10));  
  188. \r\n\r\n
  189.                 }  
  190. \r\n\r\n
  191.                 else 
  192. \r\n\r\n
  193.                 {  
  194. \r\n\r\n
  195.                     //产生1个大写字母  
  196. \r\n\r\n
  197.                     code = (char) (\'A\' + (char) (number%26));  
  198. \r\n\r\n
  199.                 }  
  200. \r\n\r\n
  201.                 checkCode += code.ToString();  
  202. \r\n\r\n
  203.             }  
  204. \r\n\r\n
  205.             return checkCode;  
  206. \r\n\r\n
  207.         }  
  208. \r\n\r\n
  209.  
  210. \r\n\r\n
  211.  
  212. \r\n\r\n
  213.         public bool IsReusable  
  214. \r\n\r\n
  215.         {  
  216. \r\n\r\n
  217.             get { return false; }  
  218. \r\n\r\n
  219.         }  
  220. \r\n\r\n
  221.     }  
  222. \r\n\r\n
  223. \r\n
\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2546, 'a-first-cpp', '创建第一个Win32窗体程序', '2013-10-24 06:00:00', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

\r\n

1.打开VS,新建项目,语言选择Visual C++,项目类型选择Win32->Win32项目,点击确定:

\r\n

在接下来的对话框中,选择下一步:

\r\n

接下来,把空项目前面的复选框勾上,点击完成:

\r\n

2.在源文件上点击添加->新建项,选择cpp文件。点击添加:

\r\n

3.在刚才新建的cpp文件里输入以下代码:

\r\n

源码

\r\n
\r\n
 
\r\n
    \r\n
  1. #include <Windows.h>   
  2. \r\n
  3. #include <stdio.h>   
  4. \r\n
  5.   
  6. \r\n
  7. LRESULT CALLBACK WinTerwerProc(   
  8. \r\n
  9.     HWND hwnd,      // handle to window   
  10. \r\n
  11.     UINT uMsg,      // message identifier   
  12. \r\n
  13.     WPARAM wParam,  // first message parameter   
  14. \r\n
  15.     LPARAM lParam   // second message parameter   
  16. \r\n
  17.     );   
  18. \r\n
  19.   
  20. \r\n
  21. int WINAPI WinMain(HINSTANCE hInstance,    
  22. \r\n
  23.     HINSTANCE hPrevInstance,   
  24. \r\n
  25.     LPSTR lpCmdLine,    
  26. \r\n
  27.     int nShowCmd )   
  28. \r\n
  29. {   
  30. \r\n
  31.   
  32. \r\n
  33.     WNDCLASS wndclass;   
  34. \r\n
  35.     wndclass.hbrBackground=(HBRUSH)GetStockObject(DKGRAY_BRUSH);   
  36. \r\n
  37.     wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);   
  38. \r\n
  39.     wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);   
  40. \r\n
  41.     wndclass.hInstance=hInstance;   
  42. \r\n
  43.     wndclass.lpfnWndProc=WinTerwerProc;   
  44. \r\n
  45.     wndclass.lpszClassName=TEXT(\"terwer\");   
  46. \r\n
  47.     wndclass.lpszMenuName=NULL;   
  48. \r\n
  49.   
  50. \r\n
  51.     wndclass.style=CS_HREDRAW||CS_VREDRAW;   
  52. \r\n
  53.     wndclass.cbClsExtra=0;   
  54. \r\n
  55.     wndclass.cbWndExtra=0;   
  56. \r\n
  57.   
  58. \r\n
  59.     RegisterClass(&wndclass);   
  60. \r\n
  61.     HWND hwnd;   
  62. \r\n
  63.     hwnd=CreateWindow(TEXT(\"terwer\"),   
  64. \r\n
  65.         TEXT(\"唐有炜\"),   
  66. \r\n
  67.         WS_OVERLAPPEDWINDOW,   
  68. \r\n
  69.         CW_USEDEFAULT,   
  70. \r\n
  71.         CW_USEDEFAULT,   
  72. \r\n
  73.         CW_USEDEFAULT,   
  74. \r\n
  75.         CW_USEDEFAULT,   
  76. \r\n
  77.         NULL,   
  78. \r\n
  79.         NULL,   
  80. \r\n
  81.         hInstance,   
  82. \r\n
  83.         NULL   
  84. \r\n
  85.         );   
  86. \r\n
  87.   
  88. \r\n
  89.     ShowWindow(hwnd,SW_SHOWNA);   
  90. \r\n
  91.   
  92. \r\n
  93.     UpdateWindow(hwnd);   
  94. \r\n
  95.   
  96. \r\n
  97.     MSG msg;   
  98. \r\n
  99.     while(GetMessage(&msg,NULL,0,0))   
  100. \r\n
  101.     {   
  102. \r\n
  103.         TranslateMessage(&msg);   
  104. \r\n
  105.         DispatchMessage(&msg);   
  106. \r\n
  107.     }   
  108. \r\n
  109.     return 0;   
  110. \r\n
  111. }   
  112. \r\n
  113.   
  114. \r\n
  115.   
  116. \r\n
  117. LRESULT CALLBACK WinTerwerProc(   
  118. \r\n
  119.     HWND hwnd,      // handle to window   
  120. \r\n
  121.     UINT uMsg,      // message identifier   
  122. \r\n
  123.     WPARAM wParam,  // first message parameter   
  124. \r\n
  125.     LPARAM lParam   // second message parameter   
  126. \r\n
  127.     )   
  128. \r\n
  129. {   
  130. \r\n
  131.     switch(uMsg)   
  132. \r\n
  133.     {   
  134. \r\n
  135.     case WM_CHAR:   
  136. \r\n
  137.         char szChar[20];   
  138. \r\n
  139.         sprintf(szChar,\"char is %c\",wParam);   
  140. \r\n
  141.         MessageBox(hwnd,szChar,\"terwer\",0);   
  142. \r\n
  143.         break;   
  144. \r\n
  145.     case WM_LBUTTONDOWN:   
  146. \r\n
  147.         MessageBox(hwnd,\"mouse clicked\",\"terwer\",0);   
  148. \r\n
  149.         HDC hdc;   
  150. \r\n
  151.         hdc=GetDC(hwnd);   
  152. \r\n
  153.         TextOut(hdc,0,50,\"唐有炜的VC\",strlen(\"VC学习\"));   
  154. \r\n
  155.         ReleaseDC(hwnd,hdc);   
  156. \r\n
  157.         break;   
  158. \r\n
  159.     case WM_PAINT:   
  160. \r\n
  161.         HDC hDC;   
  162. \r\n
  163.         PAINTSTRUCT ps;   
  164. \r\n
  165.         hDC=BeginPaint(hwnd,&ps);   
  166. \r\n
  167.         TextOut(hDC,0,0,\"呵呵\",strlen(\"呵呵\"));   
  168. \r\n
  169.         EndPaint(hwnd,&ps);   
  170. \r\n
  171.         break;   
  172. \r\n
  173.     case WM_CLOSE:   
  174. \r\n
  175.         if(IDYES==MessageBox(hwnd,\"是否真的结束?\",\"terwer\",MB_YESNO))   
  176. \r\n
  177.         {   
  178. \r\n
  179.             DestroyWindow(hwnd);   
  180. \r\n
  181.         }   
  182. \r\n
  183.         break;   
  184. \r\n
  185.     case WM_DESTROY:   
  186. \r\n
  187.         PostQuitMessage(0);   
  188. \r\n
  189.         break;   
  190. \r\n
  191.     default:   
  192. \r\n
  193.         return DefWindowProc(hwnd,uMsg,wParam,lParam);   
  194. \r\n
  195.     }   
  196. \r\n
  197.     return 0;   
  198. \r\n
  199. }   
  200. \r\n
\r\n

效果如下:

\r\n

\"fc\"

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2547, 'video-no-ad', '教你真正无广告看优酷、腾讯、56、乐视、163、凤凰、PPS、CNTV、Ku6视频(非广告屏蔽)', '2013-12-06 16:00:00', '2019-03-25 21:29:22', '[copy]youku-no-ad[/copy]\r\n

支持的网站

\r\n注:目前仅支持优酷、腾讯、56、乐视、163、凤凰、PPS、CNTV、Ku6后期会支持更多。 \r\n

使用方法

\r\n1.首先在优酷复制视频播放地址\r\n\r\n2.然后,进入\r\n\r\nhttp://Search.xinValue.Com\r\n\r\n在搜索框输入youku,例如:\r\n\r\n在搜索框输入youku 视频地址:\r\n\r\nhttp://v.youku.com/v_show/id_XNjE0MjI4MzY4.html\r\n\r\n或\r\n\r\n\"\" http://www.tudou.com/albumplay/p9nMfF_Yp_o/YpSHsdK0zn8.html \r\n\r\n\"\" http://www.letv.com/ptv/vplay/2186681.html \r\n\r\n\"\" http://www.56.com/u62/v_MTAyMDc0MTU1.html \r\n\r\n\"\" http://v.ifeng.com/mil/mainland/201312/015c1a24-c72f-4d2b-a4cb-a8f6d41af323.shtml \r\n\r\n\"\" http://v.163.com/jishi/V6FMS3ID2/V9EQ97HVH.html \r\n\r\n\"\" http://v.ku6.com/film/show_136486/qETJXF_C6evwHJwU0BXFVw...html \r\n\r\n\"\" http://v.pps.tv/play_359IM1.html \r\n\r\n\"\" http://tv.cntv.cn/video/C10302/786b97540f2646928f641ab5dca8e4ad \r\n\r\n\"\" http://v.qq.com/cover/o/o980e6tg681gd9z/w0013rj184u.html \r\n\r\n点击搜索,奇迹马上出现!视频立即播放,没有一秒广告。\r\n

更新历史

\r\n2013-12-21 增加视频搜索和评论查看。\r\n\r\n2013-12-09 视频地址加密。\r\n\r\n2013-12-04 增加56和乐视无广告播放。\r\n\r\n2013-11-04 增加土豆无广告播放。(已失效,紧急修复中。。。)\r\n\r\n2013-10-05 搜索升级,输入视频地址,可以显示标题。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2548, 'youku-auto-play', '如何让优酷网视频自动播放', '2013-10-23 06:00:00', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

先去优酷的网站www.youku.com ­,找一个你喜欢的视频 ,然后照下面做。 ­

找到这个视频的地址,例如我找到的的一个地址:­

http://player.youku.com/player.php/sid/XMjcxNjIzMDAw/v.swf

然后把地址输入到地址栏,输入地址栏之后得到这个地址,红色部分是要修改的地址.如下:

http://static.youku.com/v1.0.0367/v/swf/loader.swf?VideoIDS=XMjcxNjIzMDAw&embedid=MTIzLjg1Ljk4LjE3OQI2NzkwNTc1MAIC&wd=&vext=pid%3D%26emb%3DMTIzLjg1Ljk4LjE3OQI2NzkwNTc1MAIC%26bc%3D%26type%3D0

在上面那个地址末尾添加下面的红色色部分就是自己播放地址,如下:

http://static.youku.com/v1.0.0216/v/swf/loader.swf?VideoIDS=XMjcxNjIzMDAw&embedid=MjE4LjIwMC43MC45MgI2NzkwNTc1MAIC=&isAutoPlay=true&embedid

下面是两个地址的对比:

  1. http://static.youku.com/v1.0.0216/v/swf/loader.swf?VideoIDS=XMjcxNjIzMDAw&embedid=MjE4LjIwMC43MC45MgI2NzkwNTc1MAIC 
  1. http://static.youku.com/v1.0.0216/v/swf/loader.swf?VideoIDS=XMjcxNjIzMDAw&embedid=MjE4LjIwMC43MC45MgI2NzkwNTc1MAIC=&isAutoPlay=true&embedid  
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2553, 'wordpress-static-without-rewrite-in-iis', 'wordpress在iis下无rewrite利用cos-html-cache实现纯静态页面', '2013-10-22 06:00:00', '2019-03-25 21:29:22', '

【版权声明:本文转载自游子网络,版权归原作者。如需转载,请务必在转载时注明原文地址。】

cos-html-cache是个很不错的,可以生成静态html文件的插件,可是如作者所说“cos-html-cache插件是需要urlrewrite支持的,不幸的是这个条件已经将国内的70%的虚拟主机挡在门外了”,我也是因为虚拟主机不支持urlrewrite的原因,一直徘徊在实现html静态页面都大门之外。今天,偶然在网上看到了一篇关于这方面的文章,大受启发,通过对cos-html-cache的原理分析,终于找到了解决方案。

首先cos- html-cache的原理就是,当访问者请求一个网址的时候,如/html/2013/04/10/38.html,服务器首先会去相关的文件夹(/html/2013/04/10/)下寻找文件(38.html)是否存在,如果存在则直接将该文件发送给浏览者,否则发送一个404文件未找到的错误给浏览者,所以我们只要设置好IIS的404错误页面,当访问出现404错误的时候,自动访问相应页面即可,剩下都任务交给cos-html-cache来处理,它会自动为你生成html文件

第一步,在网站根目录新建一个404.php文件,内容如下:

  1. <?php  
  2. // This is the default file for the site. Usually index.php  
  3. $default= \'index.php\';  
  4.        
  5. // The name of this file.  
  6. // Set this value for the URL in Custom Error Properties of your website in IIS.  
  7. // Goto: IIS Manager > Websites > [Site Name] > Properties > Custom Errors >  
  8. // 404 & 404;2 & 404;3 > URL (Requires a \'/\' prefix in IIS).  
  9. $thisfile= \'404-handler.php\';  
  10.        
  11. $_SERVER[\'ORIG_PATH_TRANSLATED\'] = str_replace($thisfile, $default, $_SERVER[\'ORIG_PATH_TRANSLATED\']);  
  12. $_SERVER[\'SCRIPT_FILENAME\'] = str_replace($thisfile, $default, $_SERVER[\'SCRIPT_FILENAME\']);  
  13. $_SERVER[\'ORIG_PATH_INFO\'] = str_replace($thisfile, $default, $_SERVER[\'ORIG_PATH_INFO\']);  
  14. $_SERVER[\'SCRIPT_NAME\'] = str_replace($thisfile, $default, $_SERVER[\'SCRIPT_NAME\']);  
  15. $_SERVER[\'PHP_SELF\'] = str_replace($thisfile, $default, $_SERVER[\'PHP_SELF\']);  
  16. $_SERVER[\'PATH_INFO\'] = false;  
  17.        
  18. $qs=& $_SERVER[\'QUERY_STRING\'];  
  19. $ru=& $_SERVER[\'REQUEST_URI\'];  
  20. $pos= strrpos($qs, \'://\');  
  21. $pos= strpos($qs, \'/\', $pos+ 4);  
  22. $_SERVER[\'URL\'] = $ru= substr($qs, $pos);  
  23. $qs= trim(stristr($ru, \'?\'), \'?\');  
  24.        
  25. // Required for WordPress 2.8+  
  26. $_SERVER[\'HTTP_X_ORIGINAL_URL\'] = $ru;  
  27.        
  28. // Fix GET vars  
  29. foreach( $_GETas$var=> $val) {  
  30. if( substr($var, 0, 3) == \'404\') {  
  31. if( strstr($var, \'?\') ) {  
  32. $newvar= substr($var, strpos($var, \'?\') + 1);  
  33. $_GET[$newvar] = $val;  
  34. }  
  35. unset($_GET[$var]);  
  36. }  
  37. <\r\nspan>break;  
  38. }  
  39. include($default);  
  40. ?> 

第二步,在IIS的网站属性-自定义错误里面,将404错误的地址改成URL形式的,地址为/404.php

\"1\"

第三步,将永久链接改成自定义的一个访问路径,如/%postname%.html

\"2\"

(注,前三步亦可参考另一篇文章:WordPress伪静态的实现(不需要.htaccess))

第四步,安装上cos-html-cache,在插件里点击启用,享受html带给你的速度吧(如果没有正确生成html,请参考cos-html-cache的说明文件)

希望所有用IIS作php服务器并且无法用urlrewrite的武林同道,wordpress生成html成功!

特别提醒:最新版的要求主机必须支持URLrewrite,也成功的完成了IIS的rewrite,但就是只生成首页,但不确定是什么时候生成的。没办法,把最新的cos-html-cache2.7.3删除了,安装了早期的手动生成文件的1.1版本,修改固定连接,比如本站为:/postname%.html。然后启用cos-html-cache,发现成功了。

下载地址:cos-html-cache.1.1.zip

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2555, '7261-5', '13-10-21 21:28:36', '2013-10-21 21:28:36', '2019-03-26 00:23:15', '源码\r\n\r\n$$intnolimit_0^{frac{pi}{2}}{xf(sin x)}dx={frac{pi}{2}}intnolimit_0^{frac{pi}{2}}{f(sin x)}dx$$\r\n\r\n演示\r\n

,', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2556, '7261-6', '13-10-21 19:13:53', '2013-10-21 19:13:53', '2019-03-25 21:29:22', '\'latex\'/', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2557, '7261-7', '13-10-21 17:58:51', '2013-10-21 17:58:51', '2019-03-25 21:29:22', '今天多看一点点,疑惑就少一点点。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2558, 'modify-hotnewspro-blockquote-style', '美化HotNewsPro的引用样式', '2013-10-21 16:00:00', '2019-03-25 21:29:22', '

我们经常会引用一些内容,这些内容一般包含在<blockquote></blockquote>中,但笔者觉得默认的不太美观,于是就尝试修改一下。先上效果图

修改前:

\"1\"

修改后:

\"2\"

修改方法:

用ftp软件打开/wwwroot/wp-content/themes/HotNewspro/css/下的css.css文件,找到第23行,将.entry blockquote {}的代码修改成如下的代码:

  1. .entry blockquote {  
  2.     width: 660px;  
  3.     color: #4e6384;  
  4.     line-height: 23px;  
  5.     margin: 5px auto 5px auto;  
  6.     padding: 10px;  
  7.     clear: both;  
  8.     border: 1px solid #ccc;  
  9.     color: #4e6384;  
  10.     line-height: 23px;  
  11.     margin: 5px auto 5px auto;  
  12.     padding: 10px;  
  13.     clear: both;  
  14.     border: 1px solid #ccc;  
  15.         border-width: 1px 1px 1px 8px;  
  16.         border-style: solid;  
  17.         border-color: rgb(221, 221, 221);  
  18.        -moz-border-top-colors: none;  
  19.        -moz-border-right-colors: none;  
  20.        -moz-border-bottom-colors: none;  
  21.        -moz-border-left-colors: none;  
  22.        border-image: none;  
  23.        background-color: rgb(233, 233, 233);  
  24.        overflow: auto;    
  25.     } 
修改后,切记用360清空一下缓存,然后重新打开页面即可看到效果。

\"2\"

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2559, 'is-wp-static-cache-good', '是好心还是误导,浅谈WordPress静态化', '2013-10-20 16:00:00', '2019-03-25 21:29:22', '

【版权声明:本文转载自游子网络,版权归原作者。如需转载,请务必在转载时注明原文地址。】

最近游子遇到了好几位童鞋,他们都找到游子说我的主题为何安装不了,我明明修改了主题为什么没有变化。等等诸多WordPress方面的问题。我就纳闷了这样的情况不应该发生才对,后来与他们交谈中了解到他们分别都安装了cos-html-cache或者wp-super-cache静态化缓存插件。

\"\"

我一看就知道了问题就出在cos-html-cachewp-super-cache这两个插件上,在这里不是说cos-html-cachewp-super-cache这两个静态化插件不好,这两个插件还是很好的,在你懂用会用需要用的时候使用这插件还是可以的。我问他们为什么要安装cos-html-cache、wp-super-cache静态化缓存插件,他们的回答都是“静态,快一点”, Oh my god!我立刻就想到他们一定是看了别人介绍这两个插件说有多好有多好所以自己也就用了。到底是好心还是误导,cos-html-cache、wp- super-cache插件本身是没问题的,但什么时候用,在什么情况下用很多人都没搞懂,懵懵懂懂的就安装用上了,“嗯,访问果然快了。真的只是心理作用吧了。”

什么时候用cos-html-cache、wp-super-cache静态化缓存插件,在什么情况下用呢?

游子在这里有两点建议:

1、如果你的站访问量很大,这个很大没有一定的概念!游子认为如果你的站每天有几千IP的时候再用静态化缓存插件也不迟!

2、主题已经确定下来,应该修改的地方都修改好,以后不会再改主题或者改的范围小。这时安装静态化缓存插件也不迟!

刚开始建站真的没必要使用静态化缓存插件的,如果你想带来不必要的麻烦那你就去折腾吧。还有就是别一看到别人说好,就觉得好自己拿过来就用,你看看用的是不是时候有没有必要用。你看看介绍插件好的人他有没有用静态化缓存,说不定他都没用他只是说好,因为他知道副作用大!

不要再折腾了,用心把网站的内容做好,开启伪静态就OK了。(WordPress伪静态设置方法)追求静态化缓存只会给你带来不必要的麻烦,等有一天你技术高明了再用也不迟。

声明:此文并非说cos-html-cache、wp-super-cache静态化缓存插件不好,这里想表明的是静态化缓存不是每个人都适用,不是别人说好就用,要有自己的观点和立场。什么时候用适合,在什么情况下用适合。

笔者感受:笔者之前一直用cos-html-cache,遇到了很多问题,最后干脆直接伪静态了,因此,就像博主说的,该不该用需要你自己去权衡。

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2560, 'wp-plugin-n-chars-out-of-memory', 'Worspress插件开发新手问题,遇到“这个插件在启用的过程中产生了 3 个字符的异常输出。如果您遇到了“headers already sent”错误、联合 feed(如 RSS)出错等问题,请尝试禁用或移除本插件。”', '2013-10-19 22:00:00', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

今天尝试着做WP插件,搜了下资料,随便写了个例子,代码很简单,

  1. <?php  
  2. /*  
  3. Plugin Name: 新价值网测试插件  
  4. Plugin URI:http://www.xinvalue.com/aboutme/  
  5. Description: 新价值网致力于电脑技术,软件编程,源码分享,网站建设等领域,秉承“新技术!新价值!”的理念,力求创建一个高质量的技术交流平台!  
  6. Version: 1.0  
  7. Author: terwer  
  8. Author URI: http://www.xinvalue.com  
  9. */ 
  10. echo \'http://www.xinvalue.com\';  
  11. ?> 

但是在安装的时候报了下面这样的错误:

这个插件在启用的过程中产生了 3个字符的异常输出。如果您遇到了“headers already sent”错误、联合 feed(如 RSS)出错等问题,请尝试禁用或移除本插件。

\"1\"

网上查了很多方案没解决,于是想不是代码的问题,就是编码的问题,呵,一试,果然,下面就给大家分享一下吧:

保存文件时要选用UTF-8切记不能按BOM保存,最好用Editplus,选择另存为

\"2\"

 

\"2\"

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2561, 'import-posts-from-dedecms-or-otcms-to-wordpress', '巧用XML将织梦CMS等系统的文章导入Wordpress的完美解决方案(亲身经历,独家原创)', '2013-10-19 17:04:01', '2019-12-03 12:42:13', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

之前一直想把自己以前的旧文章导入进来,一直没有时间。反正都要做的,免得以后忘记了,那就今天吧。

笔者之前曾经用过网钛文章管理系统织梦文章管理系统,13年7月份才转入Wordpress。

至于辗转几个系统,其中原因很多,现在想想,尽管这两个系统都是相当成熟和优秀的,当初还是有一些理由让我转移阵地。从网钛到织梦,其实很纠结,当时主要原因还是因为网钛是ASP的,笔者当时学的是Java,Jsp,C#,对ASP不熟,并且很讨厌ASP的语法,而笔者有很喜欢捣鼓编程,自定义功能,所以就像换了。换了织梦后很不错,收录很好,也很稳定,可是后来由于觉得织梦是CMS,不适合博客,于是又转向了Wordpress至今。

其实现在想想,抛弃织梦还有一些后悔,因为,抛弃了SEO就白做了,流量神马的损失惨重,哎,算了不说了。不扯了,切正题吧。下面说说笔者的转换步骤。

 

先说一下项目结构吧:

\"1\"

第一步:准备好文章的XML文件。

这个很简单,数据库基本上都提供XML导出的。这个不必多说。需要说明的是,只需要导出文章一张表即可。例如我导出的OT_info.xml,article.xml(注:由于XMl文件涉及笔者隐私,就不提供下载了,尽请谅解),其实就是有文章的哪一张表。

第二步:弄清XMl结构,解析XML文档,建立对应的Model类。

(PS:由于笔者空间支持.NET,所以笔者使用C#写的),将XML数据转移到List集合中存储(这一步至关重要,完成了这一步就完成了90%)。

首先,以织梦为例,他导出来的XML文件结构大致如下:

  1. <?xml version="1.0" encoding="utf-8" ?>   
  2. <data>   
  3.     <row>   
  4.         <Id>文章ID</Id>   
  5.         <Title>文章标题</Title>   
  6.         <TypeName>分类目</TypeName>   
  7.         <TypeId>分类ID</TypeId>   
  8.         <TypeId2>分类ID2</TypeId2>   
  9.         <Flag></Flag>   
  10.         <Litpic></Litpic>   
  11.          <PubDate>发布时间</PubDate>   
  12.            <RedirectUrl></RedirectUrl>   
  13.          <UserIp></UserIp>   
  14.          <Body>正文</Body>   
  15.      </row>   
  16.     <row>   
  17.         <Id>文章ID</Id>   
  18.         <Title>文章标题</Title>   
  19.         <TypeName>分类目</TypeName>   
  20.         <TypeId>分类ID</TypeId>   
  21.         <TypeId2>分类ID2</TypeId2>   
  22.         <Flag></Flag>   
  23.         <Litpic></Litpic>   
  24.          <PubDate>发布时间</PubDate>   
  25.            <RedirectUrl></RedirectUrl>   
  26.          <UserIp></UserIp>   
  27.          <Body>正文</Body>   
  28.      </row>   
  29. </data>    

那么就先建立Model类(Row.cs),代码如下:

  1. using System;    
  2. using System.Collections.Generic;    
  3. using System.Linq;    
  4. using System.Web;    
  5.     
  6. namespace Web.Import    
  7. {    
  8.     public class Row    
  9.     {    
  10.         private int _Id;    
  11.         private string _Title;    
  12.         private string _TypeName;    
  13.         private int _TypeId;    
  14.         private int _TypeId2;    
  15.         private string _Flag;    
  16.         private string _Litpic;    
  17.         private DateTime _PubDate;    
  18.         private string _RedirectUrl;    
  19.         private string _UserIp;    
  20.         private string _Body;    
  21.     
  22.         public int Id    
  23.         {    
  24.             get { return _Id; }    
  25.             set { _Id = value; }    
  26.         }    
  27.     
  28.         public string Title    
  29.         {    
  30.             get { return _Title; }    
  31.  &\r\n#160;          set { _Title = value; }    
  32.         }    
  33.     
  34.         public string TypeName    
  35.         {    
  36.             get { return _TypeName; }    
  37.             set { _TypeName = value; }    
  38.         }    
  39.     
  40.         public int TypeId    
  41.         {    
  42.             get { return _TypeId; }    
  43.             set { _TypeId = value; }    
  44.         }    
  45.     
  46.         public string Flag    
  47.         {    
  48.             get { return _Flag; }    
  49.             set { _Flag = value; }    
  50.         }    
  51.     
  52.         public int TypeId2    
  53.         {    
  54.             get { return _TypeId2; }    
  55.             set { _TypeId2 = value; }    
  56.         }    
  57.     
  58.         public string Litpic    
  59.         {    
  60.             get { return _Litpic; }    
  61.             set { _Litpic = value; }    
  62.         }    
  63.     
  64.         public DateTime PubDate    
  65.         {    
  66.             get { return _PubDate; }    
  67.             set { _PubDate = value; }    
  68.         }    
  69.     
  70.         public string RedirectUrl    
  71.         {    
  72.             get { return _RedirectUrl; }    
  73.             set { _RedirectUrl = value; }    
  74.         }    
  75.     
  76.         public string UserIp    
  77.         {    
  78.             get { return _UserIp; }    
  79.             set { _UserIp = value; }    
  80.         }    
  81.     
  82.         public string Body    
  83.         {    
  84.             get { return _Body; }    
  85.             set { _Body = v\r\nalue; }    
  86.         }    
  87.     }    
  88. }    

接下来,就是解析XML文档,提取数据存储到List集合了。笔者的思想是把XMl文档对象建立放在构造函数中,然后再分别写两个方法来存储文章数据。其中主要是遍历XML文档,分别提取每一个元素,建立Model对象,把元素的值赋给Model对象,然后依次把Model对象存到List集合中。这是后续操作的关键,如果这一步失败,后面就无从进行了。以下是完整代码:<--reply end-->

  1. using System;    
  2. using System.Collections.Generic;    
  3. using System.Linq;    
  4. using System.Web;    
  5. using System.Xml;    
  6.     
  7. namespace Web.Import    
  8. {    
  9.     /*    
  10.    * 使用方法:调用GetRowByName("") 获取所有文章对应的List    
  11.    * XML文件规范:见该本页代码底部    
  12.    *     
  13.    * 作者:terwer    
  14.    * BLOG:http://www.xinvalue.com    *     
  15.    */    
  16.     
  17.     public class XMLHelper    
  18.     {    
  19.         private XmlNodeList nodeList;    
  20.     
  21.         public XMLHelper(string xmlFilePath)    
  22.         {    
  23.             XmlDocument doc = new XmlDocument();    
  24.             doc.Load(xmlFilePath);    
  25.             nodeList = doc.SelectNodes("/data//row");    
  26.         }    
  27.     
  28.         /// <summary>    
  29.         /// 是否为网钛    
  30.         /// </summary>    
  31.         /// <param name="xmlFilePath"></param>    
  32.         /// <param name="isOt"></param>    
  33.         public XMLHelper(string xmlFilePath, bool isOt)    
  34.         {    
  35.             if (isOt)    
  36.             {    
  37.                 XmlDocument doc = new XmlDocument();    
  38.                 doc.Load(xmlFilePath);    
  39.                 nodeList = doc.SelectNodes("/dataroot//OT_info");    
  40.             }    
  41.             else    
  42.             {    
  43.                 XmlDocument doc = new XmlDocument();    
  44.                 doc.Load(xmlFilePath);    
  45.                 nodeList = doc.SelectNodes("/data//row");    
  46.             }    
  47.         }    
  48.     
  49.         /// <summary>    
  50.         /// 获取织梦文章列表    \r\n;
  51.         /// </summary>    
  52.         public List<Row> GetRowList()    
  53.         {    
  54.             Row row;    
  55.             List<Row> rowList = new List<Row>();    
  56.     
  57.             foreach (XmlNode xmlNode in nodeList)    
  58.             {    
  59.                 row = new Row();    
  60.                 row.Id = int.Parse(xmlNode["Id"].InnerText);    
  61.                 row.Title = xmlNode["Title"].InnerText;    
  62.                 row.TypeName = xmlNode["TypeName"].InnerText;    
  63.                 row.TypeId = int.Parse(xmlNode["TypeId"].InnerText);    
  64.                 row.TypeId2 = int.Parse(xmlNode["TypeId2"].InnerText);    
  65.                 row.Flag = xmlNode["Flag"].InnerText;    
  66.                 row.Litpic = xmlNode["Litpic"].InnerText;    
  67.                 row.PubDate = TransTime(xmlNode["PubDate"].InnerText);    
  68.                 row.RedirectUrl = xmlNode["RedirectUrl"].InnerText;    
  69.                 row.UserIp = xmlNode["UserIp"].InnerText;    
  70.                 row.Body = xmlNode["Body"].InnerText;    
  71.                 rowList.Add(row);    
  72.             }    
  73.             return rowList;    
  74.         }    
  75.     
  76.         /// <summary>    
  77.         /// 获取网钛文章列表    
  78.         /// </summary>    
  79.         public List<OT_Info> GetOTRowList()    
  80.         {    
  81.             OT_Info otInfo;    
  82.             List<OT_Info> otInfoList = new List<OT_Info>();    
  83.     
  84.             foreach (XmlNode xmlNode in nodeList)    
  85.             {    
  86.                 otInfo = new OT_Info();    
  87.                 otInfo.IfId = int.Parse(xmlNode["IF_ID"].InnerText);    
  88.                 otInfo.IfTheme = xmlNode["IF_theme"].InnerText;    
  89.                 otInfo.IfImg = xmlNode["IF_img"].InnerText;    
  90.                 otInfo.IfTime = DateTime.Parse(setTime(xmlNode["IF_time"].InnerText));    
  91.                 otInfo.IfRevTime = DateTime.Parse(setTime(xmlNode["IF_revTime"].InnerText));    
  92.                 otInfo.IfContent = xmlNode["IF_content"].InnerText;    
  93.                 otInfoList.Add(otInfo);    
  94.             }    
  95.             return otInfoList;    
  96.         }    
  97.     
  98.     
  99.         /// <summary>    
  100.         /// 获取一共有多少条指令    
  101.         /// </summary>    
  102.         public int Count    
  103.         {    
  104.             get { return nodeList.Count; }    
  105.         }    
  106.     
  107.         /// <summary>    
  108.         /// 将时间戳转换为时间    
  109.         /// </summary>    
  110.         /// <param name="timeStamp">时间戳</param>    
  111.         /// <returns>时间</returns>    
  112.         private DateTime TransTime(string timeStamp)    
  113.         {    
  114.             DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));    
  115.             long lTime = long.Parse(timeStamp + "0000000");    
  116.             TimeSpan toNow = new TimeSpan(lTime);    
  117.             DateTime dtResult = dtStart.Add(toNow);    
  118.             return dtResult;    
  119.         }    
  120.     
  121.         /// <summary>    
  122.         /// 将系统时间转换为时间戳    
  123.         /// </summary>    
  124.         /// <returns></returns>    
  125.         private string ToStamp()    
  126.         {    
  127.             DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));    
  128.             DateTime dtNow = DateTime.Parse(DateTime.Now.ToString());    
  129.             TimeSpan toNow = dtNow.Subtract(dtStart);    
  130.             string timeStamp = toNow.Ticks.ToString();    
  131.             timeStamp = timeStamp.Substring(0, timeStamp.Length - 7);    
  132.             return timeStamp;    
  133.         }    
  134.     
  135.         private string setTime(string t)    
  136.         {    
  137.             return ReplaceChar(t, \'T\', \' \');    
  138.         }    
  139.     
  140.         private string ReplaceChar(string str, char chr1, char chr2)    
  141.         {    
  142.             if (st\r\nring.IsNullOrEmpty(str))    
  143.             {    
  144.                 throw new Exception("String input can not be null");    
  145.             }    
  146.     
  147.             string result = "";    
  148.     
  149.             for (int i = 0; i < str.Length; i++)    
  150.             {    
  151.                 if (str[i] != chr1)    
  152.                 {    
  153.                     result += str[i];    
  154.                 }    
  155.                 else    
  156.                 {    
  157.                     result += chr2;    
  158.                 }    
  159.             }    
  160.     
  161.             return result;    
  162.         }    
  163.     }    
  164. }   

代码比较多,我慢慢解释吧。其中有一些函数,是一些特殊处理的。核心的就GetRowList()和GetOTRowList()两个方法。仔细分析这两个函数,其实很简单,无非就是数据转存,即,经过这一步,数据已经由陌生的XML文件转移到了coder们熟悉的List<>集合中了(注意:这里用了泛型)。其实,这一步,笔者也就结了很久。

完成了第二步,第三部就简单了。

第三部我们只需遍历刚得到的List集合,不断创建Wordpress的post对象,将他们的值分别赋给post对象,然后进行插入即可(具体的由于闭合之前封装好,就不洗说了,有不明白的可以下方留言),主要代码如下(以导入织梦为例);

  1. try 
  2.           {  
  3.               XMLHelper helper = new XMLHelper(Server.MapPath("./article.xml"));  
  4.               List<Row> rowList = helper.GetRowList();  
  5.  
  6.               //Row row = rowList.ToArray()[0];  
  7.               foreach (var row in rowList)  
  8.               {  
  9.                   Model.wp_posts post = new wp_posts();  
  10.                   post.post_author = 1;  
  11.                   post.post_date = new MySql.Data.Types.MySqlDateTime(row.PubDate);  
  12.                   post.post_date_gmt = new MySqlDateTime(row.PubDate);  
  13.                   post.post_content = row.Body;  
  14.                   post.ping_status = "";  
  15.                   post.post_status = "private";  
  16.                   post.comment_status = "open";  
  17.                   post.ping_status = "open";  
  18.                   post.post_title = row.Title;  
  19.                   //DateTime.Now.ToLocalTime().ToLongDateString() + " " + DateTime.Now.ToLocalTime().ToLongTimeString();  
  20.   &#\r\n160;               post.post_name = row.Title;  
  21.                   post.post_excerpt = "";  
  22.                   post.post_password = "";  
  23.                   post.to_ping = "";  
  24.                   post.pinged = "";  
  25.                   post.post_content_filtered = "";  
  26.                   post.post_mime_type = "";  
  27.                   post.post_modified = new MySqlDateTime(row.PubDate);  
  28.                   post.post_modified_gmt = new MySqlDateTime(row.PubDate);  
  29.                   post.post_parent = 0;  
  30.                   //post.guid = "http://www.xinvalue.com/index.php?p=";  
  31.                   post.menu_order = 0;  
  32.                   post.post_type = "post";  
  33.                   post.comment_count = 0;  
  34.  
  35.                   BLL.Post postBll = new Post();  
  36.                   bool status = false;  
  37.                   status = postBll.AddFeelPosts(post);  
  38.                   if (status)  
  39.                   {  
  40.                       Response.Write("<span style=\'color:green\'>文章" + row.Title + "导入成功" + "</span><br/>");  
  41.                   }  
  42.                   else 
  43.                   {  
  44.                       Response.Write("<span style=\'color:red\'>文章" + row.Title + "</span>导入失败!<br/>");  
  45.                   }  
  46.               }  
  47.               Response.Write("导入完成" + "共导入" + rowList.Count + "条记录。");  
  48.           }  
  49.           catch (Exception ex)  
  50.           {  
  51.               Response.Write(ex.Message);  
  52.           } 

附上post的Model类

  1. using System;     
  2. namespace Model    
  3. {    
  4.     /// <summary>    
  5.     /// wp_posts:实体类(属性说明自动提取数据库字段的描述信息)    
  6.     /// </summary>    
  7.     [Serializable]    
  8.     public partial class wp_posts    
  9.     {    
  10.         public wp_posts()    
  11.         {    
  12.         }    
  13.     
  14.         #region Model    
  15.     
  16.         private ulong _id;    
  17.         private ulong _post_author = 0;    
  18.         private MySql.Data.Types.MySqlDateTime _post_date=new MySql.Data.Types.MySqlDateTime(DateTime.Now);     
  19.         private MySql.Data.Types.MySqlDateTime _post_date_gmt=new MySql.Data.Types.MySqlDateTime(DateTime.Now);     
  20.         private string _post_content;    
  21.         private string _post_title;    
  22.         private string _post_excerpt;    
  23.         private string _post_status = "publish";    
  24.         private string _comment_status = "open";    
  25.         private string _ping_status = "open";    
  26.         private string _post_password;    
  27.         private string _post_name;    
  28.         private string _to_ping;    
  29.         private string _pinged;    
  30.         private MySql.Data.Types.MySqlDateTime _post_modified =  new MySql.Data.Types.MySqlDateTime(DateTime.Now);    
  31.         private MySql.Data.Types.MySqlDateTime _post_modified_gmt = new MySql.Data.Types.MySqlDateTime(DateTime.Now);    
  32.         private string _post_content_filtered;    
  33.         private ulong _post_parent = 0;    
  34.         private string _guid;    
  35.         private int _menu_order = 0;    
  36.         private string _post_type = "post";    
  37.         private string _post_mime_type;    
  38.         private long _comment_count = 0;    
  39.     
  40.         /// <summary>    
  41.         /// auto_increment    
  42.         /// </summary>    
  43.         public ulong ID    
  44.         {    
  45.             set { _id = value; }    
  46.             get { return _id; }    
  47.         }    
  48.     
  49.         /// <summary>    
  50.         ///     
  51.         /// </summary>    
  52.         public ulong post_author    
  53.         {    
  54.       \r\n      set { _post_author = value; }    
  55.             get { return _post_author; }    
  56.         }    
  57.     
  58.         /// <summary>    
  59.         ///     
  60.         /// </summary>    
  61.         public MySql.Data.Types.MySqlDateTime post_date    
  62.         {    
  63.             set { _post_date = value; }    
  64.             get { return _post_date; }    
  65.         }    
  66.     
  67.         /// <summary>    
  68.         ///     
  69.         /// </summary>    
  70.         public MySql.Data.Types.MySqlDateTime post_date_gmt    
  71.         {    
  72.             set { _post_date_gmt = value; }    
  73.             get { return _post_date_gmt; }    
  74.         }    
  75.     
  76.         /// <summary>    
  77.         ///     
  78.         /// </summary>    
  79.         public string post_content    
  80.         {    
  81.             set { _post_content = value; }    
  82.             get { return _post_content; }    
  83.         }    
  84.     
  85.         /// <summary>    
  86.         ///     
  87.         /// </summary>    
  88.         public string post_title    
  89.         {    
  90.             set { _post_title = value; }    
  91.             get { return _post_title; }    
  92.         }    
  93.     
  94.         /// <summary>    
  95.         ///     
  96.         /// </summary>    
  97.         public string post_excerpt    
  98.         {    
  99.             set { _post_excerpt = value; }    
  100.             get { return _post_excerpt; }    
  101.         }    
  102.     
  103.         /// <summary>    
  104.         ///     
  105.         /// </summary>    
  106.         public string post_status    
  107.         {    
  108. \r\n
  109.             set { _post_status = value; }    
  110.             get { return _post_status; }    
  111.         }    
  112.     
  113.         /// <summary>    
  114.         ///     
  115.         /// </summary>    
  116.         public string comment_status    
  117.         {    
  118.             set { _comment_status = value; }    
  119.             get { return _comment_status; }    
  120.         }    
  121.     
  122.         /// <summary>    
  123.         ///     
  124.         /// </summary>    
  125.         public string ping_status    
  126.         {    
  127.             set { _ping_status = value; }    
  128.             get { return _ping_status; }    
  129.         }    
  130.     
  131.         /// <summary>    
  132.         ///     
  133.         /// </summary>    
  134.         public string post_password    
  135.         {    
  136.             set { _post_password = value; }    
  137.             get { return _post_password; }    
  138.         }    
  139.     
  140.         /// <summary>    
  141.         ///     
  142.         /// </summary>    
  143.         public string post_name    
  144.         {    
  145.             set { _post_name = value; }    
  146.             get { return _post_name; }    
  147.         }    
  148.     
  149.         /// <summary>    
  150.         ///     
  151.         /// </summary>    
  152.         public string to_ping    
  153.         {    
  154.             set { _to_ping = value; }    
  155.             get { return _to_ping; }    
  156.         }    
  157.     
  158.         /// <summary>    
  159.         ///     
  160.         /// </summary>    
  161.         public string pinged    
  162. \r\n        {    
  163.             set { _pinged = value; }    
  164.             get { return _pinged; }    
  165.         }    
  166.     
  167.         /// <summary>    
  168.         ///     
  169.         /// </summary>    
  170.         public MySql.Data.Types.MySqlDateTime post_modified    
  171.         {    
  172.             set { _post_modified = value; }    
  173.             get { return _post_modified; }    
  174.         }    
  175.     
  176.         /// <summary>    
  177.         ///     
  178.         /// </summary>    
  179.         public MySql.Data.Types.MySqlDateTime post_modified_gmt    
  180.         {    
  181.             set { _post_modified_gmt = value; }    
  182.             get { return _post_modified_gmt; }    
  183.         }    
  184.     
  185.         /// <summary>    
  186.         ///     
  187.         /// </summary>    
  188.         public string post_content_filtered    
  189.         {    
  190.             set { _post_content_filtered = value; }    
  191.             get { return _post_content_filtered; }    
  192.         }    
  193.     
  194.         /// <summary>    
  195.         ///     
  196.         /// </summary>    
  197.         public ulong post_parent    
  198.         {    
  199.             set { _post_parent = value; }    
  200.             get { return _post_parent; }    
  201.         }    
  202.     
  203.         /// <summary>    
  204.         ///     
  205.         /// </summary>    
  206.         public string guid    
  207.         {    
  208.             set { _guid = value; }    
  209.             get { return _guid; }    
  210.         }    
  211.     
  212.         /// <summary>    
  213.         ///     
  214.         /// </summary>    
  215.         public int me\r\nnu_order    
  216.         {    
  217.             set { _menu_order = value; }    
  218.             get { return _menu_order; }    
  219.         }    
  220.     
  221.         /// <summary>    
  222.         ///     
  223.         /// </summary>    
  224.         public string post_type    
  225.         {    
  226.             set { _post_type = value; }    
  227.             get { return _post_type; }    
  228.         }    
  229.     
  230.         /// <summary>    
  231.         ///     
  232.         /// </summary>    
  233.         public string post_mime_type    
  234.         {    
  235.             set { _post_mime_type = value; }    
  236.             get { return _post_mime_type; }    
  237.         }    
  238.     
  239.         /// <summary>    
  240.         ///     
  241.         /// </summary>    
  242.         public long comment_count    
  243.         {    
  244.             set { _comment_count = value; }    
  245.             get { return _comment_count; }    
  246.         }    
  247.     
  248.         #endregion Model    
  249.     }    
  250. }    

BLL主要方法

  1. /// <summary>    
  2. /// 添加心情文章    
  3. /// </summary>   
  4. /// <param name="post">文章</param>    
  5. /// <returns>结果</returns>    
  6. public bool AddFeelPosts(Model.wp_posts post)    
  7. {    
  8.     //添加文章    
  9.     post.guid = "http://www.xinvalue.com/v2/feeling/index.html";    
  10.     bool flag = new DAL.Post().Add(post);    
  11.  
  12.     //添加关系    
  13.     Model.Wp_Term_Relationships relationships = new Wp_Term_Relationships();    
  14.     relationships.object_id = new DAL.Post().GetLatestPostID();    
  15.     relationships.term_taxonomy_id = 16; //16代表心情随笔    
  16.     relationships.term_order = 0;    
  17.     flag = new DAL.TermRelationships().Add(relationships);    
  18.     return flag;    
  19. }    

其他的代码就不一一列出了,有兴趣的可以留言给我。

好了,最后就是见证奇迹的时刻了。

导入运行效果如下:

\"2\"

 

\"3\"

 

\"4\"

 

\"5\"

至此,导入成功。

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2562, 'a-multi-search-engine-by-jquery', 'Jquery实现的一款简单的复合搜索引擎(包含百度、谷歌、360搜索等)', '2013-10-19 16:59:25', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

\r\n

代码如下:

\r\n
\r\n
 
\r\n
    \r\n
  1. <!--  
  2. \r\n
  3. /*  
  4. \r\n
  5. *@Author terwer  
  6. \r\n
  7. *@Blog http://www.xinvalue.com  
  8. \r\n
  9. *@Email cbgtyw@gmail.com  
  10. \r\n
  11. *@Date 2013-10-19 16;21  
  12. \r\n
  13. @Desceiption Jquery实现的一款简单的符合搜索引擎(包含百度、谷歌、360搜索等)  
  14. \r\n
  15. --> 
  16. \r\n
  17. <script type=\"text/javascript\" src=\"http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js\">script> 
  18. \r\n
  19. <center>   
  20. \r\n
  21. <div> 
  22. \r\n
  23.     <input id=\"s\" value=\"新价值网\" style=\"font-size: 24px; font-family: \'华文宋体\', \'Tahoma\', \'微软雅黑\'; color: black; line-height: 20px;width:400px;\" type=\"text\"> 
  24. \r\n
  25.     <input value=\"\" style=\"background:url(http://sandbox.runjs.cn/uploads/rs/371/0j2ujing/buttons.gif);height:38px;width:90px\" id=\"submitButton\" type=\"submit\"> 
  26. \r\n
  27.     div>   
  28. \r\n
  29.     <div> 
  30. \r\n
  31. <input id=\"self\" name=\"soGroup\" value=\"self\" checked=\"checked\" type=\"radio\"><label for=\"self\">站内label> 
  32. \r\n
  33. <input id=\"baidu\" name=\"soGroup\" value=\"baidu\" type=\"radio\"><label for=\"baidu\">百度label> 
  34. \r\n
  35. <input id=\"google\" name=\"soGroup\" value=\"google\" type=\"radio\"><label for=\"google\">谷歌label> 
  36. \r\n
  37.  <input id=\"threeSo\" name=\"soGroup\" value=\"threeSo\" type=\"radio\"><label for=\"threeSo\">360搜索label> 
  38. \r\n
  39. <input id=\"soso\" name=\"soGroup\" value=\"soso\" type=\"radio\"><label for=\"soso\">搜搜label> 
  40. \r\n
  41. <input id=\"sogou\" name=\"soGroup\" value=\"sogou\" type=\"radio\"><label for=\"sogou\">搜狗label> 
  42. \r\n
  43. <input id=\"youdao\" name=\"soGroup\" value=\"youdao\" type=\"radio\"><label for=\"youdao\">有道label> 
  44. \r\n
  45. <input id=\"bing\" name=\"soGroup\" value=\"bing\" type=\"radio\"><label for=\"bing\">必应label> 
  46. \r\n
  47.  div> 
  48. \r\n
  49.  center> 
  50. \r\n
  51. <script type=\"text/javascript\"> 
  52. \r\n
  53.       
  54. \r\n
  55.     //URL统一编码  
  56. \r\n
  57.         function URLencode(sStr) {  
  58. \r\n
  59.                 return escape(sStr).replace(/+/g, \'%2B\').replace(/\"/g, \'%22\').replace(/\'/g, \'%27\').replace(///g, \'%2F\');  
  60. \r\n
  61.             }  
  62. \r\n
  63.       
  64. \r\n
  65.             //测试遍历处理radio点击事件  
  66. \r\n
  67.             $(\"input[type=radio]\").bind(\'click\', function(event) {  
  68. \r\n
  69.                 //alert($(this).next().text()); //被点击的radio的label的值  
  70. \r\n
  71.                 var rls = $(\'input:radio[name=\"soGroup\"]:checked\').val();  
  72. \r\n
  73.                 if (rls == null) {  
  74. \r\n
  75.                     alert(\"什么也没选中!\");  
  76. \r\n
  77.                     return false;  
  78. \r\n
  79.                 } else {  
  80. \r\n
  81.                     alert(rls);  
  82. \r\n
  83.                 }  
  84. \r\n
  85.             });  
  86. \r\n
  87.     $(\"#submitButton\").click(function(){  
  88. \r\n
  89.     //选中的radio值,根据他来判断  
  90. \r\n
  91.                 var rl = $(\'input:radio[name=\"soGroup\"]:checked\').val();  
  92. \r\n
  93.                  //alert(rl);             
  94. \r\n
  95.                   //搜索关键词  
  96. \r\n
  97.                 //var lenKey = URLencode($(\"#s\").val());  
  98. \r\n
  99.                 var lenKey = $(\"#s\").val();  
  100. \r\n
  101.                 if (rl == \"self\") { //站内搜索  
  102. \r\n
  103.                                     document.location.href =\"http://search.xinvalue.com/go/?kw=\"+lenKey;  
  104. \r\n
  105.                     return false;  
  106. \r\n
  107.                     //alert(\"站内\");  
  108. \r\n
  109.                 } else if (rl == \"baidu\") {  
  110. \r\n
  111.                                     document.location.href =\"http://www.baidu.com/s?wd=\"+$(\"#s\").val();  
  112. \r\n
  113.                                     //alert(\"百度\");  
  114. \r\n
  115.                     return false;  
  116. \r\n
  117.                 } else if (rl == \"google\") {  
  118. \r\n
  119.                                     document.location.href =\"http://www.google.com.hk/search?q=\"+$(\"#s\").val();   
  120. \r\n
  121.                   //  alert(\"谷歌\");  
  122. \r\n
  123.                 } else if (rl == \"threeSo\") {  
  124. \r\n
  125.                                         document.location.href =\"http://www.so.com/s?q=\"+$(\"#s\").val();  
  126. \r\n
  127.                   // alert(\"360搜索\");  
  128. \r\n
  129.                 } else if (rl == \"soso\") {  
  130. \r\n
  131.                                         document.location.href =\"http://www.soso.com/q?w=\"+$(\"#s\").val();  
  132. \r\n
  133.                                     // alert(\"搜索\");  
  134. \r\n
  135.                 } else if (rl == \"sogou\") {  
  136. \r\n
  137.                                     document.location.href =\"http://www.sogou.com/web?query=\"+$(\"#s\").val();  
  138. \r\n
  139.                                     //alert(\"搜狗\");  
  140. \r\n
  141.                 } else if (rl == \"youdao\") {  
  142. \r\n
  143.                                         document.location.href =\"http://www.youdao.com/search?q=\"+$(\"#s\").val();  
  144. \r\n
  145.                                     //alert(\"有道\");  
  146. \r\n
  147.                 } else if (rl == \"bing\") {  
  148. \r\n
  149.                                         document.location.href =\"http://www.bing.com/search?q=\"+$(\"#s\").val()+\"&pq=\"+$(\"#s\").val();  
  150. \r\n
  151.                                     //alert(\"必应\");  
  152. \r\n
  153.                 } else {  
  154. \r\n
  155.                     alert(\"错误\");  
  156. \r\n
  157.                     return false;  
  158. \r\n
  159.                 }  
  160. \r\n
  161.     });  
  162. \r\n
  163. script> 
  164. \r\n
\r\n

演示:

\r\n

http://sandbox.runjs.cn/show/ytjv0guh

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2563, 'csharp-clipboard', 'C#剪贴板操作', '2013-10-19 14:02:00', '2019-03-25 21:29:22', '

复制操作:

  1. private void textBox1_Click(object sender, EventArgs e)  
  2.        {  
  3.            if (textBox1.Text != "")  
  4.            {  
  5.                Clipboard.SetDataObject(textBox1.Text);  
  6.                MessageBox.Show("复制成功!");  
  7.            }  
  8.        } 

粘贴操作:

  1. private void textBox1_Click(object sender, EventArgs e)  
  2.        {  
  3.            IDataObject idata = Clipboard.GetDataObject();  
  4.            if (idata.GetDataPresent(DataFormats.Text))  
  5.            {  
  6.                textBox1.Text = (string) idata.GetData(DataFormats.Text);  
  7.                MessageBox.Show("粘贴成功!");  
  8.            }  
  9.        } 
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2564, 'set-wordpress-permanent-link', 'wordpress固定链接的设置,超简单就能让网站实现静态', '2013-10-19 07:15:05', '2019-03-25 21:29:22', '

【版权声明:本文转载自http://www.ncw52.com,版权归原作者。如需转载,请务必在转载时注明原文地址。】

固定链接其实就是修改 WordPress 目录、页面或者帖子的URL链接形式,修改这个的好处,一个是地址更好识别,如果有一定规律的话,用户体验会非常好,其次就是SEO优化,修改之后的静态地址比动态地址更容易让搜索引擎接受,从而更快的提高我们博客的排名,用更短的时间让更多人知道你的博客。由此可见,固定链接在博客中的重要性。对于wordpress 用户而言,就很有必要掌握一些固定连接的设置参数和技巧。

永久链接设置参数:

参数按照WordPress官方文档列表如下:

1. %year%

基于文章发布年份,比如2012;

2. %monthnum%

基于文章发布月份,比如05;

3. %day%

基于文章发布当日,比如28;

4. %hour%

基于文章发布小时数,比如15;

5. %minute%

基于文章发布分钟数,比如43;

6. %second%

基于文章发布秒数,比如33;

7. %postname%

基于文章的postname,其值为撰写时指定的缩略名,不指定缩略名时是文章标题;

8. %post_id%

基于文章post_id,比如423;

9. %category%

基于文章分类,子分类会处理成“分类/子分类”这种形式;

10. %author%

基于文章作者名。

将上述参数进行组合,即可得到wordpress的固定链接形式。

网上常见的几种设置方法:

* /%year%/%monthnum%/%day%/%postname%/

* /%year%/%monthnum%/%postname%/

* /%year%/%monthnum%/%day%/%postname%.html

* /%year%/%monthnum%/%postname%.html

* /%category%/%postname%.html(推荐形式)

*/%postname%.html(推荐形式)

* /%post_id%.html

永久链接设置原则:

一、不要让日期出现在固定连接链接里面

这基于两个方面的考虑。一是如果数字出现在固定链接里面,等于提醒搜索引擎,这是很旧的内容了,没必要再爬一遍了。另外一个原因是,假如你要修改文章的日期重新发布的话,链接地址就变了,也就是意味着你的反向链接,PR 等等都没有了。

二、不要让分类的链接出现在固定链接里面

这一点是很多人都会忽略的地方。让分类出现在固定链接里面有两个缺陷:一是一篇文章如果选择了多个分类的话,则会出现多个链接地址,这很容易造成因为重复内容而被搜索引擎惩罚;二是有可能会造成关键词堆砌而被搜索引擎惩罚。

三、链接不宜过深

经常看到很多wordpress 朋友的固定链接是年/月/日/分类名/文章名。但是这种过于深的固定链接对搜索引擎是非常不友好的。

四、不要让中文字符出现在固定链接里面

虽然现在的搜索引擎已经能识别URL地址里面的中文字符,但无论是从美观上,还是从wordpress 优化的角度来看,都是非常差的。

好了,赶快设置下自己网站的固定链接吧!在操作中出现了什么问题,也欢迎您向我们提问。

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2565, 'create-a-windows-live-writer-plugin', '为Windows Live Writer开发插件', '2013-10-19 06:38:47', '2019-03-25 21:29:22', '

第一步:在Visual Studio中创建项目

打开Visual Studio,选择Visual C#,创建一个“类库”类型的项目(注意: .NET Frameword版本要选3.0,不能选4.0,否则插件运行不了,务必谨记 )。

\"1111\"

然后在项目中添加WindowsLive.Writer.Api.dll程序集的引用(一般位于C:Program Files (x86)Windows LiveWriter文件夹中),以及相应的System.Drawing、System.Windows.Forms等引用。添加好之后效果如下:

\"2\"

右键单击该项目,选择“属性”。在“生成事件”选项卡中的“后期生成时间命令行”中写入如下命令,让每次编译完成之后自动将该插件拷贝到Windows Live Writer的插件目录下:

  1. XCOPY /D /Y /R "$(TargetPath)" "C:Program Files (x86)Windows LiveWriterPlugins"   

\"3\"

第二步:继承于ContentSource基类

接下来,让我们在这个项目中新建一个类,并继承于WindowsLive.Writer.Api.ContentSource基类

  1. using System; 
  2. using System.Collections.Generic; 
  3. using System.Linq; 
  4. using System.Text; 
  5. using WindowsLive.Writer.Api; 
  6.  
  7. namespace WindowsLiveWriterInsertCode 
  8.     [WriterPlugin("8C92B331-1218-413D-8F1E-C91B934A0389", "插入代码"
  9.     PublisherUrl = "http://www.xinvalue.com"
  10.     ImagePath = "code.bmp"
  11.     Description = "插入代码的插件。")] 
  12.     [InsertableContentSource("插入代码")] 
  13.     public class InserCodePlugin : WindowsLive.Writer.Api.ContentSource 
  14.     { 
  15.         //... 
  16.     } 
注意我们为该类添加了WriterPlugin属性:
  1. 第一个参数为一个Guid,我们可以用Visual Studio自动生成,其标识的作用。
  2. \"4\"
  3. \"5\"
  4. 第二个参数为该插件的名称,将在Windows Live Writer的插件管理器中看到:
  5. PublisherUrl为发布者的网站地址,这里就写了我的Blog地址。
  6. ImagePath为插件的图标文件路径,注意该图标应为18*16大小,且一定以Embedded Resource形式编译在程序集中。如下:
  7. \"7\"
    1. Description为插件的一小段描述介绍。

    该类还应用了InsertableContentSource属性,其中的参数表示“插入”菜单和“插入”快捷面板中该插件的名称。

    \"8\"

    第三步:覆写基类的CreateContent()方法

    CreateContent()方法用来得到该插件所生成的一个HTML字符串,一旦用户点击了“插入”菜单快捷面板中的“插入XXX”链接,Windows Live Writer就将自动调用该方法,所以我们应该在该方法中弹出一个小窗口用来配置讲要插入的内容。

    该方法的代码如下:

    1. public override DialogResult CreateContent(IWin32Window dialogOwner, ref string newContent) 
    2.        { 
    3.            using (InsertCodeForm insertCodeForm = new InsertCodeForm()) 
    4.            { 
    5.                DialogResult result = insertCodeForm.ShowDialog(); 
    6.                newContent = insertCodeForm.codeHTMLString; 
    7.                return result; 
    8.            } 
    9.        } 
  8.  

    注意到CreateContent()方法的第二个参数为ref string newContent,这个ref string就表示由该插件生成的HTML代码。

    该方法的实现也非常简单,仅仅是创建了一个InsertCodeForm,然后就将所有任务都交给了它。

    第四步:编写InsertCodeForm

    InsertCodeForm就是一个再普通不过的WinForm了,一个TextBox、一个代码选择ComboBox和一“插入代码”按钮。设计期界面如下:

    \"9\"

回到InsertCodeForm的代码中,为该类添加一个公有属性,用来表示该Form配置后生成的HTML字符串:

  1. private string m_codeHTMLString; 
  2.  
  3.  public string codeHTMLString 
  4.      get { return m_codeHTMLString; } 
  5.      set { m_codeHTMLString = value; } 

然后是“插入代码”按钮的事件处理函数,只是简单地格式化并生成一段HTML,然后保留在m_linkHTMLString中而已:

  1. private void btnInsert_Click(object sender, EventArgs e) 
  2.      { 
  3.          m_codeHTMLString = "tyw"//这里是处理代码,未写出(仅仅演示用) 
  4.          this.DialogResult = DialogResult.OK; 
  5.      } 

 

这样,当用户在InsertLinkForm中配置完成之后点击“插入代码”按钮,将执行上述事件处理函数,其中生成HTML字符串并保留在m_linkHTMLString中,然后该Form将被关闭。

之后该Form的调用者——CreateContent()方法将得到该InsertCodeForm的LinkHTMLString属性,并将其交给Windows Live Writer。以后的事情,自有Windows Live Writer为我们完成。搞定!

第五步:调试插件

编写程序不需要调试是不可思议的,哪怕这个最简单的小程序也不例外。可是,这个“插件”类型的程序应该如何调试呢?

记得在前面我们已经设置了项目的后期完成生成事件,每次编译成功之后将自动将编译结果拷贝到Windows Live Writer的插件目录中。这时若你启动Windows Live Writer,则可以看到该插件已经被顺利加载了进去,当然,前提是插件没有致命错误。

然后,我们可以在Visual Studio中点击调试附加到进程

\"11\"

然后手工将Visual Studio的Debugger附加到这个Windows Live Writer的实例中。注意代码类型我们需要选择托管:

\"12\"

\"13\"

这样在Visual Studio中的插件代码中加入断点,然后切换回Windows Live Writer,启动该插件,Visual Studio将顺利开始调试。

附:相关资源

  1. Windows Live Writer的SDK:Windows Live Writer SDK
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2566, '1764-2', 'Wordpress查询时间为空的文章并修改为现在时间', '2013-10-17 14:04:34', '2019-03-25 21:29:22', '

查出时间为空的文章:

  1. SELECT * FROM Wp_Posts where  
  2. post_date_gmt=\'0000-00-00 00:00:0\' OR 
  3. post_date=\'0000-00-00 00:00:0\' OR 
  4. post_modified=\'0000-00-00 00:00:0\' OR 
  5. post_modified_gmt=\'0000-00-00 00:00:0\'  

修改时间:

  1. UPDATE  Wp_Posts SET post_date=now() where post_date=\'0000-00-00 00:00:0\'; 
  2. UPDATE  Wp_Posts SET post_date_gmt=now() where post_date_gmt=\'0000-00-00 00:00:0\'; 
  3. UPDATE  Wp_Posts SET post_modified=now() where post_modified=\'0000-00-00 00:00:0\'; 
  4. UPDATE  Wp_Posts SET post_modified_gmt=now() where post_modified_gmt=\'0000-00-00 00:00:0\'; 
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2567, 'mysql-data-types-can-not-be-convert', '类型“MySql.Data.Types.MySqlDateTime”的对象无法转换为类型“System.DateTime”完美解决方案。', '2013-10-17 07:46:40', '2019-03-25 21:29:22', '

问题的由来

\r\n

最近想写一个文章导入的东西,把之前旧网站的数据导进来,因为笔者的空间支持.NET,于是就用C#和MySQL用CSharp开始了文章导入Wordpress的编程。但是在程序运行的时候,却出现了异常。大概内容是“无法将System.Datetime转换成MySqlDateTime”。经过网上一阵狂搜,也没找到可用的解决方案。因此打算自己尝试解决。

\r\n

最后经过一番摸索,找到了完美的解答。网上说的什么allow zero datetime=true根本不靠谱,因为根源不在这。

\r\n

一下是笔者探索的解决方法。

\r\n

完美解决方案

\r\n

经过摸索,发现MySql的datetime和CSharp的datetime有一些不同,通过获取Mysqldatetime列的DataType,发现他的DataType是MySql.Data.Types.MySqlDateTime,而不是System.DateTime。因此只需要实现用System.DateTime生成一个MySql.Data.Types.MySqlDateTime的对象,就可以和列的数据类型相匹配。
经过修改后的代码为:

\r\n

post.post_date = new MySql.Data.Types.MySqlDateTime(row.PubDate);

\r\n

即将数据类型定义为MySql.Data.Types.MySqlDateTime,而不是System.DateTime,当传入的参数为System.DateTime时,要进行类似上述代码的转换。

\r\n

感悟

\r\n

遇到问题,要多思考,有时候现有的答案也不一定是最完美的。

\r\n

 

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2568, 'c-in-unix-timestamp-and-system-time-conversion', 'c#中UNIX时间戳与系统时间相互转换', '2013-10-17 06:51:32', '2019-03-25 21:29:22', '

将时间戳转换为系统时间的代码如下:

\r\n
\r\n
 
\r\n
    \r\n
  1. ///
  2. \r\n
  3. /// 将时间戳转换为时间 
  4. \r\n
  5. ///
  6. \r\n
  7. ///时间戳 
  8. \r\n
  9. /// 时间 
  10. \r\n
  11. private DateTime TransTime(string timeStamp) 
  12. \r\n
  13. \r\n
  14.     DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1)); 
  15. \r\n
  16.     long lTime = long.Parse(timeStamp + \"0000000\"); 
  17. \r\n
  18.     TimeSpan toNow = new TimeSpan(lTime); 
  19. \r\n
  20.     DateTime dtResult = dtStart.Add(toNow); 
  21. \r\n
  22.     return dtResult; 
  23. \r\n
  24. \r\n
\r\n

 

\r\n

将系统时间转换为时间戳的代码如下:

\r\n
\r\n
 
\r\n
    \r\n
  1. ///
  2. \r\n
  3. /// 将系统时间转换为时间戳  
  4. \r\n
  5. ///
  6. \r\n
  7. ///  
  8. \r\n
  9. private string ToStamp()  
  10. \r\n
  11. {  
  12. \r\n
  13.     DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));  
  14. \r\n
  15.     DateTime dtNow = DateTime.Parse(DateTime.Now.ToString());  
  16. \r\n
  17.     TimeSpan toNow = dtNow.Subtract(dtStart);  
  18. \r\n
  19.     string timeStamp = toNow.Ticks.ToString();  
  20. \r\n
  21.     timeStamp = timeStamp.Substring(0, timeStamp.Length - 7);  
  22. \r\n
  23.     return timeStamp;  
  24. \r\n
  25. }  
  26. \r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2569, 'android-device-not-support-attribute', '安装安卓应用时提示“您的设备不支持add-on属性”的解决办法', '2013-10-16 22:31:12', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

笔者今天使用安卓手机安装应用Wolfram Alpha时,突然遇到了提示“您的设备不支持add-on属性”的情况,出现提示后软件就安装不了。

\"1\"

可是之前我也装过啊,可以的啊,于是想想会不会是只最近刷机了的缘故。于是,在网上查阅了以下资料,经过摸索,终于得出了结果。

下面笔者就分享下使用安卓手机安装软件时出现”您的设备不支持add-on属性“的解决方法。

在网上搜索一番,发现有不少机友也出现了类似情况。出现这种错误提醒大多是因为安装的软件带有运动追踪器、基站定位等功能的软件,主要原因是因为手机中缺少谷歌的服务造成的。使用安卓手机的机友一般比较喜欢刷机,刷的ROM包很多都去掉了谷歌服务套件,部分软件中所带有的类似运动追踪的功能,缺少谷歌服务是无法运行的。下面的方法就是重新把安装此类软件所必须的谷歌服务文件恢复到手机中来解决的

步骤如下:

1.首页需要 ROOT 你的手机,并且安装RE管理器(Root Explorer),不清楚如何 ROOT 请自行搜索相关教程(PS:hiapk网站有大量写的非常好的ROOT教程,笔者就不重复了)。

2.在本文下方下载运行该类软件所必须的谷歌的套件包,解压后得到三个文件。

3.使用RE管理器,把解压后的三个文件分别复制到相应的目录,如果没有,请新建该目录。三个文件对应的目录如下所示:

/system/framework/com.google.android.maps.jar

\"11\"
/system/etc/permission/com.google.android.maps.xml

\"22\"
/data/app_s/NetworkLocation.apk

  \"33\"

4.修改三个文件的权限,修改方法为:

使用RE管理器,挂载读写权限,在对应文件上长按选择“权限”命令。修改后的权限应为:左边全选,中间最上面选上,右边全空。如下图所示:

\"44\"

5.重新启动手机(务必谨记),再次安装该类软件或游戏时,就可以完美安装运行了。

\"111\"

经过以上简单的五步,就完美解决了安卓手机安装软件时提示“您的设备不支持add-on属性”的问题,笔者使用的手机型号为三星S5360,其他手机型号请各位自行测试,如遇到问题请微博留言给我。

下载地址:google.rar

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2570, 'virtual-box-set-share-forder', 'virtualbox设置共享文件夹', '2013-10-16 21:27:03', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

1、新建一个文件夹,比如/mnt/share

2、 sudo mount -t vboxsf share /mnt/share/,其中media为共享文件夹的名称

3、/mnt/share

4、ls即可。

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2571, '13-10-16-014500', '13-10-16 01:45:00', '2013-10-16 01:45:00', '2019-03-25 21:29:22', '

函数f(x,y)在(x0,y0)处可微的充分必要条件是 [limlimits_{rhoto0}{frac{Delta z-ADelta x-BDelta y}{rho}}]
\r\n预览
\r\n \'latex\'/

\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2572, '13-10-15-174348', '13-10-15 17:43:48', '2013-10-16 01:43:48', '2019-03-25 21:29:22', '把时间留给思考。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2573, 'latex', 'Latex数学符号对应表', '2014-02-10 14:22:00', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

常用符号

符号 预览
$quad$ 空格
 
 
 
 

Hebrew字母

符号 预览
$aleph$ [aleph]
$beth$ [beth]
$daleth$ [daleth]
$gimel$ [gimel]

 

 

 

 

 

 

 

 

 

\"2_thumb7\"

\"3_thumb5\"

\"4_thumb4\"

\"5_thumb6\"

\"6_thumb6\"

\"7_thumb7\"

\"8_thumb8\"

\"9_thumb6\"

\"10_thumb7\"

\"11_thumb7\"

\"12_thumb6\"

\"13_thumb7\"

\"14_thumb5\"

\"15_thumb5\"

\"16_thumb5\"

\"17_thumb5\"

\"18_thumb5\"

\"19_thumb6\"

\"20_thumb5\"

\"25_thumb7\"

\"26_thumb7\"

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2574, '13-10-15-152821', '13-10-15 15:28:21', '2013-10-15 15:28:21', '2019-03-25 21:29:22', '积分的绝对值<=绝对值的积分 left|int_{a}^{b}{f(x)dx}right|leqint_{a}^{b}{left|f(x)right|dx}\r\n预览\r\n \'latex\'/', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2575, '13-10-15-144543', '13-10-15 14:45:43', '2013-10-15 14:45:43', '2019-03-25 21:29:22', 'latex输入绝对值\r\n | {aaa} |\r\n预览\r\n \'latex\'/', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2576, '13-10-15-143224', '13-10-15 14:32:24', '2013-10-15 14:32:24', '2019-03-25 21:29:22', '每天23.30-0.00为上网时间', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2577, '1280-2', 'C#简单实现读取和写入txt文件', '2013-10-15 01:20:51', '2019-03-25 21:29:22', '

代码如下: 

  1. //写入开始 
  2. string str;           
  3. str=this.textBox2.Text;             
  4. StreamWriter sw = new StreamWriter("test.txt", false,Encoding.UTF8);             
  5. sw.WriteLine(str);             
  6. sw.Close();     
  7. //写入结束 
  8.  
  9. //读取开始 
  10. string str;             
  11. StreamReader sr = new StreamReader("test.txt", Encoding.UTF8); 
  12. string temStr; 
  13. while ((temStr = sr.ReadLine()) != null) { 
  14.                str += temStr; 
  15.            } 
  16. sr.Close(); 
  17. //读取结束 
  18.  
  19. this.textBox1.Text = str; 

读取注意事项:

路径的话分为绝对路径和相对路径,如果写的是相对路径,就是项目的exe的文件夹内,要是绝对路径就要从根目录写起如: C:\\1.txt;
另外,要记得close();

 

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2578, '13-10-14-175945', '13-10-14 17:59:45', '2013-10-14 17:59:45', '2019-03-25 21:29:22', '本周新计划:晚饭回来继续复习一小时数学。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2579, '13-10-14-172431', '13-10-14 17:24:31', '2013-10-14 17:24:31', '2019-03-25 21:29:22', '从今天开始,不再摆弄网站。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2580, '13-10-14-124710', '13-10-14 12:47:10', '2013-10-14 12:47:10', '2019-03-25 21:29:22', '注意,crc检验的被除数是移位后的。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2581, '13-10-14-124456', '13-10-14 12:44:56', '2013-10-14 12:44:56', '2019-03-25 21:29:22', '务必严格执行作息时间。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2582, '13-10-14-024323', '13-10-14 02:43:23', '2013-10-14 02:43:23', '2019-03-25 21:29:22', '默认分类,others,心情随笔,考研,高等数学,电视剧,概率论,线性代数,大学课程,大学物理这几个分类没有在首页和rss中出现。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2583, 'output-self-content', 'Wordpress中的RSS输出自定义分类中的文章内容', '2013-10-13 22:20:52', '2019-03-25 21:29:22', '

\r\n 通过在functions.php中加入下面代码即可(注意:是在主题目录下的functions.php文件,并且最好添加在最前面):\r\n

\r\n

\r\n \"1\"\r\n

\r\n
\r\n
\r\n
\r\n
    \r\n
  1. \r\n //修改于2013/10/13  \r\n
  2. \r\n
  3. \r\n //feed文章过滤  \r\n
  4. \r\n
  5. \r\n function myFilter($query) {  \r\n
  6. \r\n
  7. \r\n if ($query->is_feed) {  \r\n
  8. \r\n
  9. \r\n $query->set(\'cat\',\'-1,-11,-14,-69,-70,-80,-86,-87,-88,-99\'); //这里是要过滤掉的ID\r\n
  10. \r\n
  11. \r\n return $query\r\n
  12. \r\n
  13. \r\n \r\n
  14. \r\n
  15. \r\n add_filter(\'pre_get_posts\',\'myFilter\');  \r\n
  16. \r\n
  17. \r\n //feed文章过滤结束  \r\n
  18. \r\n
\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2584, 'summary-college-physics-on-formula', '大学物理(上)公式定理总结', '2013-10-13 15:03:46', '2019-03-26 00:24:30', '

运动学

1.基本物理量

(1) 位置矢量(运动方程)

\"\"

速度

\"\"

加速度

\"\"

\"\"

切向加速度

[a_t=frac{dv}{dt}]

法向加速度

\"\"

(2)圆周运动及刚体定轴转动的角量描述

角位移

\"\"

角速度

\"\"

角加速度

\"\"

角量与线量的关系

\"\"

\"\"

\"\"

\"\"

 

2.相对运动

\"\"

\"\"

 

质点动力学

1.牛顿三定律(略);

惯性系(略);

非惯性系(略);

惯性力:平动加速参照系

[F_惯=-ma(a为非惯性系相对惯性系的加速度)]

匀速转动参照系的惯性离心力

[F_惯=momega^2R]

2.动量

\"\"

冲量

\"\"

质点及质点系的动量定理

\"\"

动量守恒定律:

[(1)F_外=0,P=恒量]

[(2)(F_外)_{某方向}=0,P_{某方向}=恒量]

[(3)F_外leq F_内,Papprox恒量]

[(F_外)_{某方向}leq(F_{内})_{某方向},P_{某方向}=恒量]

3.功

\"\"

\"\"

功率

\"\"

动能定理

\"\"

保守力

\"\"

势能

\"\"

重力势能(以坐标原点为势能零点)

\"\"

引力势能(以无限远为势能零点)

\"\"

弹性势能(以无伸长点为势能零点)

\"\"

势能公式

\"\"

功能原理

\"\"

机械能守恒

条件 \"\"\"\"

结论 \"\"=恒量

 

刚体的定轴转动

力矩

\"\"\"\"\"\"

转动惯量

\"\"\"\"

转动定律

\"\"\"\"

角动量

质点 \"\"刚体\"\"

角动量定理

\"\"

角动量守恒

\"\"时, \"\"恒量

力矩的功

\"\"

功率

\"\"

转动动能

\"\"

刚体定轴转动的动能定理

\"\"

刚体的转动惯量跟刚体的形状,质量,密度分布,转轴位置等有关.下面列出几种常见的,形状对称、材料密度均匀的刚体绕某一些轴的转动惯量:

1.薄圆环绕垂直环面的过环心的轴转动

\"\"

2.薄圆环以环的某一直径为轴转动

\r\n

\"\"

3.圆筒绕中心轴线转动

\"\"

4.细棒绕通过中心与棒垂直的轴转动

\"\" 

5.细棒绕通过棒的一端与棒垂直的轴转动

\"\"

6.球体绕球的任一直径转动

\"\"

7.球壳绕球的任一直径转动

\"\"

8.圆柱体绕中心轴线转动

\"\"

热学部分

一、气体动理论(主要讨论理想气体)

1.状态方程[pV=frac{M}{M_{mol}}RT]

[frac{pV}{T}=常量,pV=nkT]

2.压强公式

[p=frac{1}{3}nmv^2=frac{1}{3}rho v^2=frac{2}{3}nbar{varepsilon}_t^2]

3.平均平动动能与温度的关系

[bar{w}=frac{1}{2}mbar{v}^2=frac{3}{2}kT]

4.常温下分子的自由度

单原子 [i=t=3]

双原子 [i=t+r=3+2=5]

多原子 [i=t+r=3+3=6]

5.能均分定理

每个分子每个自由度平均分得能量[frac{1}{2}kT]

每个分子的平均动能 [bar{varepsilon_k}=frac{i}{2}kT]

理想气体的内能:[E=frac{M}{M_{mol}}RT]

6.麦克斯韦速率分律:

[f(v)=frac{dN}{Ndv}=4pi(frac{m}{2pi kT})^{frac{3}{2}}e^{frac{-mv^2}{2kT}}v^2]

[v_{rms}=sqrt{bar{v}^2}=sqrt{frac{3kT}{m}}=sqrt{frac{3RT}{M_{mol}}}]

[v=sqrt{frac{8kT}{pi m}}=sqrt{frac{8RT}{pi M_{mol}}}]

[v_p=sqrt{frac{2kT}{m}}=sqrt{frac{2RT}{M_{mol}}}]

7.平均碰撞次数:

[bar{Z}=sqrt{2}pi d^2nv]

8.平均自由程:

[bar{lambda}=frac{1}{sqrt{2}pi d^2n}]

二、热力学基础

1.准静态过程(略)

2.热力学第一定律

[Q=E_2-E_1+A    dQ=dE+dA]

准静态过程的情况下:

[Q=E_2-E_1+int_{V_1}^{V_2}{pdV}    dQ=dE+pdV]

3.热容 [C=frac{dQ}{dT}]

定体摩尔热容 [C=frac{dQ}{dT}frac{V}{nu }]

定压摩尔热容 [C=frac{dQ}{dT}frac{p}{nu }]

比热容比 [gamma =frac{C_p}{C_V}]

对于理想气体:

[C_V=frac{i}{2}R]

[C_p=(frac{i}{2}+1)R]

[C_p-C_V=R]

[gamma =frac{2+i}{i}]

[4.几个等值过程的Delta E,A,Q]

等体过程

[Delta E=frac{M}{M_{mol}}C_VDelta T\\ A=0qquad Q=frac{M}{M_{mol}}C_VDelta T]

等压过程

[Delta E=frac{M}{M_{mol}}C_vDelta T\\ A=p(V_2-V_1)=pDelta V=frac{M}{M_{mol}} RDelta T qquad Q=frac{M}{M_{mol}}C_pDelta T]

[C_p=C_V+R]

等温过程

[Delta E=0\\ A=frac{M}{M_{mol}}RTlnfrac{V_2}{V_1} qquad Q=frac{M}{M_{mol}}RTlnfrac{V_2}{V_1}]

绝热过程

[PV=常量\\ Q=0\\ Delta E=frac{M}{M_{mol}}C_VDelta T qquad A=-frac{M}{M_{mol}}C_VDelta T=frac{p_1V_1-p_2V_2}{gamma -1}]

5.循环过程的效率及致冷系数:

[eta =frac{A}{Q}=1-frac{Q_2}{Q_1} \\ w=frac{Q_2}{A}=frac{Q_2}{Q_1-Q_2}]

卡诺循环: h

[eta_c=1-frac{T_2}{T_1}qquad w=frac{T_2}{T_1-T_2}]

6.可逆过程与不可逆过程(略)

7.热力学第二定律两种表述及其等价性(略)

8.熵[S=klnOmega ]

熵增原理 孤立系统中 [Delta S>0]

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2585, 'start-latex', 'latex学习笔记', '2013-10-13 14:13:35', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

Windows Live Writer是一个很好的博客客户端软件,有各种各样的插件,写起博客的来非常方便。Windows Live Writer也是博客园的推荐客户端软件。写博客的时候,有很多情况都是要插入公式的,先要转成图片,再把图片插入到博客中,这非常麻烦。

然后我就上网上找,看看有没有公式输入的插件,很遗憾的是没有找到,但是我发现Google chart api提供相应的现实latex公式的api。只要把latex公式代码传参数给google api就能很好地显示公式了。Google chart api显示latex的接口地址如下:http://chart.apis.google.com/chart?cht=tx&chl= {latex} 。{latex}部分就是显示要显示的公式的latex代码。

我学过一段时间的latex,发现它输入公式还是很方便的,但是如果要编译成pdf再截图的话,也是很麻烦的,所以为了我就想能不能利用Google chart api来实现公式插入,其实很简单只要添加一段“<img src=’图片地址’ />”就能很好地把公式加入到博客中了。

其中,latex的语法如下:

符号 预览

int_{0}^{t}{Mdt}=Jomega

lim_{x->0}{{(1+x)}^{frac{1}{x}}}=e
sumlimits_{i=1}^{n}{i}=frac{n(n+1)}{2}
vec r=r(t)=x(t)vec i+y(t)vec j+z(t)vec k
vec v=frac{dvec r}{dt}=frac{dx}{dt}{vec i}+frac{dy}{dt}{vec j}+frac{dz}{dt}{vec k}
vec a=frac{dvec v}{dt}=frac{v_x}{dt}{vec i}+frac{v_y}{dt}{vec j}+frac{v_z}{dt}{vec k}
\\qquadqquadqquadqquad =frac{d^2vec r}{dt^2}=frac{d^2x}{dt^2}{vec i}+frac{d^2y}{dt^2}{vec j}+frac{d^2z}{dt^2}{vec k}
theta=theta(t)
omega=frac{dtheta}{dt}
beta=frac{domega}{dt}=frac{d^2theta}{dt^2}
Delta l=rDeltatheta
begin{vmatrix}a&b&\\c&d\\end{vmatrix}
left|aright|
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2586, 'php-get-url-image', 'PHP获取指定网页内容中的图片地址', '2013-10-13 04:26:14', '2019-03-25 21:29:22', '

\r\n 代码如下:\r\n

\r\n
\r\n
\r\n
\r\n
    \r\n
  1. \r\n <?php  \r\n
  2. \r\n
  3. \r\n    $str=\'http://www.xinvalue.comhttp://bcs.duapp.com/terwer/blog/2013/10/aaa.jpg\" class=\"cboxElement\" rel=\"example4\" 1118\"=\"\"><img style=\"border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px\" title=\"aaa\" alt=\"aaa\" src=\"http://bcs.duapp.com/terwer/blog/2013/10/aaa_thumb.jpg\" border=\"0\" height=\"300\" width=\"644\"></a>\';  \r\n
  4. \r\n
  5. \r\n    \r\n
  6. \r\n
  7. \r\n     //$url=\"http://www.xinvalue.com/html/2013/10/13/1118.html\";   \r\n
  8. \r\n
  9. \r\n     //file_get_contents() 函数把整个文件读入一个字符串中   \r\n
  10. \r\n
  11. \r\n     //$str=file_get_contents($url);   \r\n
  12. \r\n
  13. \r\n     //preg_match_all函数进行全局正则表达式匹配。   \r\n
  14. \r\n
  15. \r\n preg_match(\'/<img.+src=\"?(.+.(jpg|gif|bmp|bnp|png))\"?.+>/i\',$str,$match);  \r\n
  16. \r\n
  17. \r\n echo $match[1];  \r\n
  18. \r\n
  19. \r\n      \r\n
  20. \r\n
  21. \r\n ?>   \r\n
  22. \r\n
\r\n
\r\n

\r\n 效果预览:\r\n

\r\n

\r\n \"php_get_url\"\r\n

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2587, 'php-get-img-and-save', 'PHP获取远程图片并把它保存到本地', '2013-10-13 04:19:13', '2019-03-25 21:29:22', '

代码如下:

\r\n
\r\n
 
\r\n
    \r\n
  1. <?php     
  2. \r\n
  3. // Function: 获取远程图片并把它保存到本地    
  4. \r\n
  5. // 确定您有把文件写入本地服务器的权限    
  6. \r\n
  7. // 变量说明:    
  8. \r\n
  9. // $url 是远程图片的完整URL地址,不能为空。    
  10. \r\n
  11. // $filename 是可选变量: 如果为空,本地文件名将基于时间和日期    
  12. \r\n
  13. // 自动生成.    
  14. \r\n
  15. function GrabImage($url,$filename=\"\") {    
  16. \r\n
  17. if($url==\"\"):return false;endif;    
  18. \r\n
  19. if($filename==\"\") {    
  20. \r\n
  21. $ext=strrchr($url,\".\");    
  22. \r\n
  23. if($ext!=\".gif\" && $ext!=\".jpg\"):return false;endif;    
  24. \r\n
  25. $filename=date(\"dMYHis\").$ext;    
  26. \r\n
  27. }    
  28. \r\n
  29. ob_start();    
  30. \r\n
  31. readfile($url);    
  32. \r\n
  33. $img = ob_get_contents();    
  34. \r\n
  35. ob_end_clean();    
  36. \r\n
  37. $size = strlen($img);    
  38. \r\n
  39. $fp2=@fopen($filename, \"a\");    
  40. \r\n
  41. fwrite($fp2,$img);    
  42. \r\n
  43. fclose($fp2);    
  44. \r\n
  45. return $filename;    
  46. \r\n
  47. }   
  48. \r\n
  49.  
  50. \r\n
  51. $img=GrabImage(\"http://www.xinvalue.com/wp-content/themes/HotNewspro/images/random/3.jpg\",\"xinValue.jpg\");    
  52. \r\n
  53. if($img):echo \"<pre><img src=\'$img\'></pre>\";    
  54. \r\n
  55. else:echo \"false\";    
  56. \r\n
  57. endif;    
  58. \r\n
  59. ?>  
  60. \r\n
\r\n

效果预览:

\r\n

\"get_pic\"

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2588, 'wordpress-add-sina-share', 'Wordpress添加新浪微博和腾讯微博分享(代码实现,可自定义来源显示)', '2013-10-13 02:23:16', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

只需将下面的代码加到wordpress主题目录的single.php的适当位置即可,例如,本博客位置

\"single\"

(需要说明的是,如果需要修改微博来源,则要修改第35行的appkey的值(特别注意这里用到的和申请的appkey还不一样,这是微博发布窗插件页面自动生成的,插件地址:http://open.weibo.com/widget/publisher.php),关于appkey的文章太多了,笔者就不在重复了,大家如果有疑问可以微博@LeaveBugsAway留言,我会尽量回答,如果你不知道怎么添加,可以看下文章末尾的视频教程)

代码如下

  1. <!--新浪微博分享开始-->                       
  2. <!--                       
  3. /**                       
  4. * WordPress添加新浪微博分享(代码实现,可自定义来源显示)                       
  5. *                       
  6. * @author Tangyouwei                       
  7. * @weibo http://weibo.com/206464069                       
  8. * @site http://www.xinvalue.com                    
  9. */                       
  10. -->                  
  11. <!--  
  12. <html xmlns:wb="http://open.weibo.com/wb">                   
  13. <script src="http://tjs.sjs.sinajs.cn/open/api/js/wb.js" type="text/javascript" charset="utf-8">    
  14. -->                 
  15. </script>                   
  16.   <div>                       
  17. <?php                       
  18.   $str=get_the_content();                       
  19.   //echo $str;                       
  20.   preg_match(\'/<img.+src="?(.+.(jpg|gif|bmp|bnp|png))"?.+>/i\',$str,$match);                       
  21.   $pic_url=$match[1];                       
  22.   //echo $pic_url;                       
  23. ?>                       
  24. <wb:publish action=\'publish\' type=\'web\' language=\'zh_cn\' button_type=\'red\'                       
  25. button_size=\'middle\'      &\r\n#160;                 
  26. button_text=\'分享到新浪微博\' uid=\'1804943403\' default_text=\'<?php                       
  27. the_title();                       
  28. echo " ";                      
  29. the_permalink();                      
  30. echo " 作者简介:http://www.xinvalue.com/aboutme/";                       
  31. echo " 原文作者:";                       
  32. ?> \' tag=\'<?php                        
  33. $categories = get_the_category();                        
  34. $src_cat=(get_category_parents($categories[0]->term_id, false,\'# #\'));                       
  35. $cat=substr($src_cat,0,strlen($src_cat)-3);//去掉多余的分隔符                       
  36. echo $cat;                       
  37. ?>\' default_image=\'<?php echo $pic_url; ?>\' refer=\'y\' appkey=\'1oy0aZ\' ></wb:publish>                       
  38. </div>                          
  39. <!--新浪微博分享结束-->                       
  40.       
  41. <!--腾讯微博分享开始-->    
  42. <div id="qqwb_share__" data-appkey="801460665" data-icon="0" data-counter="1"   
  43. data-counter_pos="right" data-content="<?php the_title();?>"   
  44. data-richcontent="<?php                        
  45. echo "新价值网 |";                       
  46. echo "http://www.xinvalue.com |";                       
  47. echo "作者:@superterwer";                       
  48. ?>"   
  49. data-pic="<?php echo $pic_url; ?>"></div> 
  50. <!--在您需要显示一键分享按钮的地方插入第一段代码--> 
  51. <script src="http://mat1.gtimg.com/app/openjs/openjs.js#autoboot=no&debug=no"></script> 
  52. <!--此</body>前插入第二段代码-->                 
  53. <!--腾讯微博分享结束-->    

效果预览

\"wp_share_weibo\"

 

\"2013-11-03_184312\"

视频教程

[youku]XNjI5OTgyMTI4[/youku]

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2589, '13-10-12-182907', '13-10-12 18:29:07', '2013-10-12 18:29:07', '2019-03-25 21:29:22', '千里之堤,溃于蚁穴。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2590, '1074', '2013-10-17 15:34:49', '2013-10-12 22:48:42', '2019-03-25 21:29:22', '\"image\"\r\n\r\n\r\n\r\n在方程组中,矩阵的秩反映的是约束条件的个数。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2591, '13-10-11-230358', '13-10-11 23:03:58', '2013-10-11 23:03:58', '2019-03-25 21:29:22', 'crc构成:信息码+余数。\r\ncrc求余数的方法:信息码先移位(位数为生成多项式的最高次数),低位补0,然后除以生成多项式。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2592, '13-10-11-224854', '13-10-11 22:48:54', '2013-10-11 22:48:54', '2019-03-25 21:29:22', '海明码公式:n+k≤2∧k-1。n是信息位,k是检验位。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2593, '13-10-11-224508', '13-10-11 22:45:08', '2013-10-11 22:45:08', '2019-03-25 21:29:22', '8421加法大于 1010时,需要加6修正,并且向高位进1。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2594, '13-10-11-215127', '13-10-11 21:51:27', '2013-10-11 21:51:27', '2019-03-25 21:29:22', 'C语言进制问题\r\n数据前面加:\r\n0x数据 十六进制\r\n0数据 八进制\r\n直接数据 十进制\r\n\r\n而 %d %o %x %X\r\n分别是 十进制,八进制,十六进制(小写),十六进制(大些)的输出格式!', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2595, '13-10-11-182245', '13-10-11 18:22:45', '2013-10-11 18:22:45', '2019-03-25 21:29:22', '越是到最后,越是要心静。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2596, '1066', '2013-10-17 15:34:49', '2013-10-12 00:47:14', '2019-03-25 21:29:22', '行列式定义问题\r\n\r\n\"image\"', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2597, '1064', '2013-10-17 15:34:49', '2013-10-12 00:38:13', '2019-03-25 21:29:22', '特殊行列式的计算技巧\r\n\r\n\"image\"', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2598, '13-10-11-163240', '13-10-11 16:32:40', '2013-10-11 16:32:40', '2019-03-25 21:29:22', '三阶行列式的计算技巧:1化成上三角和下三角 2降阶 3特殊技巧。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2599, '1050-2', '安卓手机怎么更换字体', '2013-10-11 00:09:37', '2019-03-25 21:29:22', '
1、获取root权限,确保安装有RE管理器这个软件;
2、把下载的字体命名为DroidSansFallback.ttf(
注意:DroidSans.ttf 系统默认英文字体,DroidSans-Bold.ttf 系统默认英文粗字体,DroidSansFallback.ttf 系统默认中文字体),放到SD卡,用RE管理器访问你放文件的位置,一般是/sdcard里面,长按字体文件复制、粘贴到system/fonts替换掉原来的字体(请在粘贴前修改权限为可写,RE管理器右上方)
3、修改权限(最重要的一步,否则会出现口口,看图),长按你更换的那个字体文件,出来一个列表,选择“权限”,有三排,把最上面的那一排前两个选中打钩就可以了(第二排第一个,第三排第一个也要打钩)。
4、重启机器。
附:笔者认为比较好看的几种字体
华文行楷 下载地址:http://115.com/file/c25hbvov
本文转载自:http://zhidao.baidu.com/question/311549737.html,略有改动。
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2600, '13-10-10-180434', '13-10-10 18:04:34', '2013-10-10 18:04:34', '2019-03-25 21:29:22', 'ascii码,0-31为控制字符,32是空格,127是删除,32-126为可印刷字符。\r\n0-9的ascii码值为48-57', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2601, '13-10-10-160701', '13-10-10 16:07:01', '2013-10-10 16:07:01', '2019-03-25 21:29:22', '一元三次方程x^3+px^2+qx+r=0的三个正 根是α、β、γ,则α+β+γ=-p,α β+βγ+αγ=q,αβγ=-r', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2602, '13-10-10-154538', '13-10-10 15:45:38', '2013-10-10 15:45:38', '2019-03-25 21:29:22', '克拉莫法则:1齐次,若D≠0,则只有零解。\r\n2非齐,若D≠0,则有唯一解。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2603, '13-10-09-211732', '13-10-09 21:17:32', '2013-10-09 21:17:32', '2019-03-25 21:29:22', '中断是操作系统必须提供的功能。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2604, '13-10-09-190228', '13-10-09 19:02:28', '2013-10-09 19:02:28', '2019-03-25 21:29:22', '补码定点加减法溢出判断:无论加法还是减法,只要实际参与运算的两个数符号相同,结果又与原操作数的符号不同,即为溢出。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2605, '1043', '2013-10-17 15:34:49', '2013-10-10 00:11:11', '2019-03-25 21:29:22', '\"image\"\r\n\r\n\r\n\r\n行列式的计算方法', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2606, '1041', '2013-10-17 15:34:49', '2013-10-09 23:43:00', '2019-03-25 21:29:22', '解决方程组的三个工具\r\n\r\n\"image\"', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2607, '13-10-09-140849', '13-10-09 14:08:49', '2013-10-09 14:08:49', '2019-03-25 21:29:22', '连续函数一定存在原函数。\r\n有第一类间断点的函数不存在原函数,但有第二类间断点的函数可能存在原函数。\r\n连续函数及区间上有有限个第一类间断点的函数一定可积。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2608, '13-10-09-140223', '13-10-09 14:02:23', '2013-10-09 14:02:23', '2019-03-25 21:29:22', '奇函数的原函数和导数均为偶函数。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2609, '13-10-09-115008', '13-10-09 11:50:08', '2013-10-09 11:50:08', '2019-03-25 21:29:22', '一切从实际出发,是实事求是思想路线的前提和基础;理论联系实际,是实事求是思想路线的根本途径和方法;在实践中检验和发展真理,是实事求是思想路线的验证条件和目的。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2610, '13-10-09-112446', '13-10-09 11:24:46', '2013-10-09 11:24:46', '2019-03-25 21:29:22', '科学发展观,第一要义是发展,核心是以人为本,基本要求是全面协调可持续,根本方法是统筹兼顾。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2611, '13-10-09-110809', '13-10-09 11:08:09', '2013-10-09 11:08:09', '2019-03-25 21:29:22', '毛泽东思想的活的灵魂:即实事求是,群众路线,独立自主。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2612, '13-10-09-105232', '13-10-09 10:52:32', '2013-10-09 10:52:32', '2019-03-25 21:29:22', 'xxx is one thing,xxx is another thing.\r\nxxx is one thing,xxx is something else.xxx是一回事,xxx是另一回事。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2613, '13-10-09-075854', '13-10-09 07:58:54', '2013-10-09 07:58:54', '2019-03-25 21:29:22', '正常的作息才可能保证正常的效率。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2614, '13-10-09-073624', '13-10-09 07:36:24', '2013-10-09 07:36:24', '2019-03-25 21:29:22', '坚持完成任务。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2615, '13-10-08-062550', '13-10-08 06:25:50', '2013-10-08 06:25:50', '2019-03-25 21:29:22', '88天,毫不松懈。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2616, '13-10-07-200052', '13-10-07 20:00:52', '2013-10-08 04:00:52', '2019-03-25 21:29:22', '时间不等人,所以,绝不能相互占用。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2617, 'download-microsoft-visual-c-6-0-and-hello-world', 'Microsoft Visual C++ 6.0简体中文版', '2013-10-07 12:02:00', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

\r\n

软件截图

\r\n

\"vc6\"

\r\n

安全认证

\r\n

 \"clip_image001\"360通过 \"clip_image002[8]\"金山毒霸通过\"clip_image003[8]\"瑞星通过

\r\n

\"clip_image004[8]\"卡巴通过 \"clip_image005[8]\"小红伞通过 \"clip_image006[8]\"NOD通过

\r\n

\"clip_image007[8]\"无插件  \"clip_image008[8]\"win7兼容  \"clip_image009[8]\"新价值网认证

\r\n

评价等级

\r\n

\"\"\"\"\"\"\"\"\"\"

\r\n

发布时间

\r\n

2011-10-17 19:47:56

\r\n

更新时间

\r\n

2013-07-02 19:47:56

\r\n

软件版本

\r\n

V6.0

\r\n

应用平台

\r\n

Win7/Vista/Win2003/WinXP/Win2000/

\r\n

软件介绍

\r\n

Visual C++ 6.0,简称VC或者VC6.0,是微软推出的一款C++编译器,将“高级语言”翻译为“机器语言(低级语言)”的程序。Visual C++是一个功能强大的可视化软件开发工具。自1993年Microsoft公司推出Visual C++1.0后,随着其新版本的不断问世,Visual C++已成为专业程序员进行软件开发的首选工具。虽然微软公司推出了 Visual C++.NET(Visual C++7.0),但它的应用有很大的局限性,只适用于Windows 2000、Windows XP和Windows NT4.0。所以实际中,更多的是以Visual C++6.0为平台。

\r\n

温馨提示

\r\n

由于本博客之前维护过一次,因此去年发布的下载地址已失效,通过访问记录发现有好多朋友在搜索,因此,我就再发一次。其中有两个下载地址,一个是百度云的,这个是完整版,另一个爱问的是精简版。 这是我之前闲暇时刻录制的部分视频,希望对大家有帮助:http://www.youku.com/playlist_show/id_16365995.html 由于笔者目前正考研复习,可能无法及时回复,尽请谅解。 如果大家有任何问题可以微博留言:@LeaveBugsAway,或在博文下方留言。谢谢大家对新价值网的支持,我是新价值网的博主小唐(网名terwer)。笔者已经把本软件下载积分设为了0,请放心下载。

\r\n

笔者评价

\r\n

完整版功能齐全,但安装较慢,适合有经验和多方面开发且精通者;精简版,安装迅速,去掉了复杂的组件,但基本功能已经足够初学者使用。您可以根据自己的情况下载。

\r\n

下载地址

\r\n

精简版下载地址一

\r\n

[download id=\"4\"]

\r\n

完整版下载地址一

\r\n

[download id=\"3\"]

\r\n

入门教程

\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2618, '13-10-07-110243', '13-10-07 11:02:43', '2013-10-07 11:02:43', '2019-03-25 21:29:22', 'issue sth to sb宣布,发出\r\nissue sb with sth发给,供给\r\ntake issue with sb向某人提出异议\r\nbe at issue是讨论的焦点', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2619, '13-10-07-060832', '13-10-07 06:08:32', '2013-10-07 06:08:32', '2019-03-25 21:29:22', '即使遍体鳞伤,也要战至最后一刻。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2620, '13-10-07-060729', '13-10-07 06:07:29', '2013-10-07 06:07:29', '2019-03-25 21:29:22', '记住,这是最后一次改变命运的机会。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2621, '1016', '2013-10-17 15:34:49', '2013-10-07 05:58:48', '2019-03-25 21:29:22', '\"image\"', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2622, '1014', '2013-10-17 15:34:49', '2013-10-07 05:08:06', '2019-03-25 21:29:22', '\"image\"', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2623, '1012', '2013-10-17 15:34:49', '2013-10-07 04:57:40', '2019-03-25 21:29:22', '\"image\"', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2624, '13-10-06-185820', '13-10-06 18:58:20', '2013-10-06 18:58:20', '2019-03-25 21:29:22', '由η=1-T2/T1(T2是低温热源,T1是高温热源)可知,增加高温热源和降低低温热源,可以提高热机效率,但降低低温热源效果更明显。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2625, '996', '2013-10-17 15:34:49', '2013-10-06 19:21:43', '2019-03-25 21:29:22', '

\"\"/

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2626, '994', '2013-10-17 15:34:49', '2013-10-06 19:03:15', '2019-03-25 21:29:22', '中国特色社会主义道路是实现途径,中国特色社会主义理论体系是行动指南,中国特色社会主义制度是根本保障,三者统一于中国特色社会主义伟大实践。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2627, '993', '2013-10-17 15:34:49', '2013-10-06 18:40:20', '2019-03-25 21:29:22', '1938年毛泽东在六届六中全会做《论新阶段》的政治报告,最先提出\"马克思主义中国化\"这个命题。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2628, '992', '2013-10-17 15:34:49', '2013-10-06 18:33:52', '2019-03-25 21:29:22', 'The things that brings the great xxx carry the greatest potential for ...带来xxx的事情也最有可能带来...', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2629, '991', '2013-10-17 15:34:49', '2013-10-06 18:27:54', '2019-03-25 21:29:22', 'The rise of xxx almost exactly tracks xxx,and with it...xxx现象几乎是进跟着xxx出现的...', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2630, '990', '2013-10-17 15:34:49', '2013-10-06 18:09:00', '2019-03-25 21:29:22', 'Many things make people think xxx is weird.But the weirdest may be this:很多事情让人认为xxx很奇怪,但最奇怪的是:', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2631, '989', '2013-10-17 15:34:49', '2013-10-06 17:09:31', '2019-03-25 21:29:22', 'Given all this.考虑到这些。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2632, '988', '2013-10-17 15:34:49', '2013-10-06 14:48:14', '2019-03-25 21:29:22', '只要学不死,就往死里学。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2633, '987', '2013-10-17 15:34:49', '2013-10-06 14:47:33', '2019-03-25 21:29:22', '感觉不到累,就不叫考研。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2634, '986', '2013-10-17 15:34:49', '2013-10-05 21:18:04', '2019-03-25 21:29:22', '高阶导数的定积分证明问题,一般使用泰勒公式 若高阶导数有连续性证明等式,若高阶导数没有连续性证明不等式。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2635, '983', '2013-10-17 15:34:49', '2013-10-05 20:49:22', '2019-03-25 21:29:22', 'OSI参考模型与TCP/IP协议模型及所对应PDU(协议数据单元) 对应关系。\r\n应用层=应用层,数据\r\n表示层=应用层,数据\r\n会话层=应用层,数据\r\n\r\n传输层=传输层,段\r\n\r\n网络层=网络层,包\r\n\r\n数据链路层=网络接口层,帧\r\n物理层=网络接口层,比特流', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2636, '985', '2013-10-17 15:34:49', '2013-10-05 20:45:16', '2019-03-25 21:29:22', '一个人可以没有经验,但不能没有思想。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2637, '982', '2013-10-17 15:34:49', '2013-10-05 07:49:07', '2019-03-25 21:29:22', '严格执行作息。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2638, '981', '2013-10-17 15:34:49', '2013-10-05 07:36:16', '2019-03-25 21:29:22', '\"image\"\r\n\r\n\r\n\r\nosi参考模型', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2639, '979', '2013-10-17 15:34:49', '2013-10-05 07:27:04', '2019-03-25 21:29:22', '\"image\"', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2640, '977', '2013-10-17 15:34:49', '2013-10-05 06:21:14', '2019-03-25 21:29:22', '\"image\"', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2641, '975', '2013-10-17 15:34:49', '2013-10-05 06:14:15', '2019-03-25 21:29:22', '操作系统的四个基本特征:并发、共享、虚拟和异步。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2642, '974', '2013-10-17 15:34:49', '2013-10-05 06:12:44', '2019-03-25 21:29:22', '\"image\"', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2643, '972', '2013-10-17 15:34:49', '2013-10-05 06:08:09', '2019-03-25 21:29:22', '\"image\"', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2644, '970', '2013-10-17 15:34:49', '2013-10-05 06:00:04', '2019-03-25 21:29:22', '\"image\"\r\n\r\n\r\n\r\n网络操作系统', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2645, '968', '2013-10-17 15:34:49', '2013-10-05 05:57:06', '2019-03-25 21:29:22', '\"image\"\r\n\r\n\r\n\r\n分布式操作系统', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2646, '966', '2013-10-17 15:34:49', '2013-10-05 05:53:28', '2019-03-25 21:29:22', '\"image\"\r\n\r\n\r\n\r\n分时系统和实时系统', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2647, '964', '2013-10-17 15:34:49', '2013-10-05 05:49:24', '2019-03-25 21:29:22', '\"image\"\r\n\r\n\r\n\r\n多道批处理系统的特点', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2648, '962', '2013-10-17 15:34:49', '2013-10-05 05:44:21', '2019-03-25 21:29:22', '\"image\"\r\n\r\n\r\n\r\n单道批处理系统的特点', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2649, '960', '2013-10-17 15:34:49', '2013-10-05 05:38:09', '2019-03-25 21:29:22', '\"image\"\r\n\r\n\r\n\r\n操作系统作用3', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2651, '958', '2013-10-17 15:34:49', '2013-10-05 05:36:16', '2019-03-25 21:29:22', '\"image\"\r\n\r\n\r\n\r\n操作系统作用1 2', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2652, '956', '2013-10-17 15:34:49', '2013-10-05 05:21:28', '2019-03-25 21:29:22', '在移码的传统定义中,固定的偏移量时是2^k 在IEEE32位标准中,固定的偏移量不是2^K,而是2^(k-1)-1。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2653, '955', '2013-10-17 15:34:49', '2013-10-05 05:05:12', '2019-03-25 21:29:22', '进制转换的算法\r\n\r\n\"image\"', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2654, '953', '2013-10-17 15:34:49', '2013-10-05 04:55:09', '2019-03-25 21:29:22', '规格化表示中,尾数为0.1M的形式,但在IEEE754中,尾数为1.M的形式。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2655, '952', '2013-10-17 15:34:49', '2013-10-05 04:44:22', '2019-03-25 21:29:22', '定点小数,其绝对值必须小于1,否则溢出,因此必须找合适的比例因子 浮点数仅在上溢时停止工作,一般不考虑比例因子。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2656, '951', '2013-10-17 15:34:49', '2013-10-05 04:39:41', '2019-03-25 21:29:22', '当浮点数阶码大于最大阶码时,产生上溢,程序终止运行 当浮点数阶码小于最小阶码时,由于数很小,一般强制置零,程序继续运行。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2657, '950', '2013-10-17 15:34:49', '2013-10-05 04:30:55', '2019-03-25 21:29:22', '基数越大,浮点数表示的范围越大,但精度反而下降。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2658, '949', '2013-10-17 15:34:49', '2013-10-05 04:28:56', '2019-03-25 21:29:22', '浮点数规格化时,尾数右移n位,阶码加n,尾数左移n位,阶码减n。 当基数为2时,n=1,当基数为4时,n=2,当基数为8时,n=3,当基数为16时,n=4;总结,当基数为2^k时,n=k。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2659, '948', '2013-10-17 15:34:49', '2013-10-05 03:50:41', '2019-03-25 21:29:22', '原码反码补码的求法 1正数,原码=反码=补码 2负数,符号位原码反码补码均等于1,数值位,反码是各位求反,对于补码,有两种求法①各位求反加一,②从最右边向左扫描,找到第一个数值为1的,1右边的(包括1)保持不变,1左边的各位求反。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2660, '947', '2013-10-17 15:34:49', '2013-10-05 03:37:54', '2019-03-25 21:29:22', '\"image\"', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2661, '945', '2013-10-17 15:34:49', '2013-10-05 02:51:50', '2019-03-25 21:29:22', '\"image\"', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2662, '943', '2013-10-17 15:34:49', '2013-10-05 02:43:43', '2019-03-25 21:29:22', '机器字长是机器进行一次整数运算的二进制位数。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2663, '942', '2013-10-17 15:34:49', '2013-10-05 02:29:21', '2019-03-25 21:29:22', '用效率换时间。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2664, '936', '2013-10-17 15:34:49', '2013-10-04 20:49:14', '2019-03-25 21:29:22', '若定积分区间长度与积分系数互为导数,用积分中值定理。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2665, '935', '2013-10-17 15:34:49', '2013-10-04 20:44:30', '2019-03-25 21:29:22', '在定积分证明中,若被积函数一阶可导,则有两种方法 1和一阶导数相关的量不含一阶导数,用微分中值定理 2积分中含一阶导数,用牛顿莱布尼茨公式', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2666, '933', '2013-10-17 15:34:49', '2013-10-04 20:26:49', '2019-03-25 21:29:22', '受不了自己了,出门又忘记带钥匙了。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2667, '929', '2013-10-17 15:34:49', '2013-10-04 18:49:21', '2019-03-25 21:29:22', '积分的绝对值≤绝对值的积分。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2668, '923', '2013-10-17 15:34:49', '2013-10-04 17:38:55', '2019-03-25 21:29:22', '想象需要测试去还原。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2669, 'idea-gen-javadoc', 'IntelliJ IDEA生成javadoc时,乱码问题要注意两个参数的设置', '2013-10-04 08:29:21', '2019-03-25 21:29:22', '

生成javadoc时,乱码问题要注意两个参数的设置 :

  1. -encoding utf-8 -charset utf-8  


前面的是文件编码,后面的是生成的javadoc的编码
例如用IntelliJ IDEA 11.0.1 生成javadoc时,在"Tools->Gerenate JavaDoc"面版的
"Other command line arguments:"栏里输入"-encoding utf-8 -charset utf-8",
就是以utf-8编码读取文件和生成javadoc。如图所示:

\"2013-10-04_083007\"

\"2\"

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2670, 'android-visit-ip', 'Android获取访问者ip', '2013-10-04 06:56:57', '2019-03-25 21:29:22', '代码如下:\r\n
\r\n
\r\n
\r\n
    \r\n
  1. \r\n public String getVistorIp(Context context) {  \r\n
  2. \r\n
  3. \r\n      //获取wifi服务  \r\n
  4. \r\n
  5. \r\n      WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);  \r\n
  6. \r\n
  7. \r\n   \r\n
  8. \r\n
  9. \r\n      //判断wifi是否开启  \r\n
  10. \r\n
  11. \r\n      if (!wifiManager.isWifiEnabled()) {  \r\n
  12. \r\n
  13. \r\n          wifiManager.setWifiEnabled(true);  \r\n
  14. \r\n
  15. \r\n      }  \r\n
  16. \r\n
  17. \r\n   \r\n
  18. \r\n
  19. \r\n      WifiInfo wifiInfo = wifiManager.getConnectionInfo();  \r\n
  20. \r\n
  21. \r\n   \r\n
  22. \r\n
  23. \r\n      int ipAddress = wifiInfo.getIpAddress();  \r\n
  24. \r\n
  25. \r\n   \r\n
  26. \r\n
  27. \r\n      String ip = intToIp(ipAddress);  \r\n
  28. \r\n
  29. \r\n   \r\n
  30. \r\n
  31. \r\n      return ip;  \r\n
  32. \r\n
  33. \r\n \r\n
  34. \r\n
  35. \r\n   \r\n
  36. \r\n
  37. \r\n  private String intToIp(int i) {  \r\n
  38. \r\n
  39. \r\n      return (i & 0xFF) + \".\" + ((i >> 8) & 0xFF) + \".\" + ((i >> 16) & 0xFF) +  \r\n
  40. \r\n
  41. \r\n              \".\" + ((i >> 24) & 0xFF);  \r\n
  42. \r\n
  43. \r\n \r\n
  44. \r\n
\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2671, '899', '2013-10-17 15:34:49', '2013-10-04 10:41:12', '2019-03-25 21:29:22', '怎么突然间感觉瞌睡的不行啊去,先睡会去了。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2672, '898', '2013-10-17 15:34:49', '2013-10-04 10:34:08', '2019-03-25 21:29:22', '打疲劳站,实际上是得不偿失的做法。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2673, '896', '2013-10-17 15:34:49', '2013-10-04 09:27:23', '2019-03-25 21:29:22', '去吃饭了。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2674, '890-2', 'Android取消EditText自动获取焦点默认行为', '2013-10-03 08:28:31', '2019-03-25 21:29:22', '

在项目中,一进入一个页面, EditText默认就会自动获取焦点,很是郁闷,Android 如何让EditText不自动获取焦点?于是搜集整理一番,晒出来和大家分享,希望对你们有所帮助 。

在项目中,一进入一个页面, EditText默认就会自动获取焦点。
那么如何取消这个默认行为呢?
在网上找了好久,有点 监听软键盘事件,有点 调用 clearFouse()方法,但是测试了都没有! xml中也找不到相应的属性可以关闭这个默认行为
解决之道:在EditText的父级控件中找一个,设置成

  1. android:focusable="true"  
  2. android:focusableInTouchMode="true"   

这样,就把EditText默认的行为截断了!

代码如下:

  1. <LinearLayout  
  2. style="@style/FillWrapWidgetStyle"  
  3. android:orientation="vertical"  
  4. android:background="@color/black"  
  5. android:gravity="center_horizontal"  
  6. android:focusable="true"  
  7. android:focusableInTouchMode="true"  
  8. >  
  9. <ImageView  
  10. android:id="@+id/logo"  
  11. style="@style/WrapContentWidgetStyle"  
  12. android:background="@drawable/dream_dictionary_logo"  
  13. />  
  14. <RelativeLayout  
  15. style="@style/FillWrapWidgetStyle"  
  16. android:background="@drawable/searchbar_bg"  
  17. android:gravity="center_vertical"  
  18. >  
  19. <EditText  
  20. android:id="@+id/searchEditText"  
  21. style="@style/WrapContentWidgetStyle"  
  22. android:background="@null"  
  23. android:hint="Search"  
  24. android:layout_marginLeft="40dp"  
  25. android:singleLine="true"  
  26. />  
  27. </RelativeLayout>  
  28. </LinearLayout>   
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2675, '889-2', 'Android的ListView点击事件与跳转', '2013-10-03 06:48:53', '2019-03-25 21:29:22', '

代码如下:

  1. private class FeelingClickListener implements AdapterView.OnItemClickListener { 
  2.         @Override 
  3.         public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { 
  4.             String postId = null
  5.             final TextView selItem = (TextView) view; 
  6.             //Log.i("text", "" + selItem.getText().toString()); 
  7.  
  8.             List<NameValuePair> params = new ArrayList<NameValuePair>(); 
  9.             params.add(new BasicNameValuePair("page", txt_page.getText().toString())); 
  10.             params.add(new BasicNameValuePair("num", txt_num.getText().toString())); 
  11.  
  12.             try
  13.                 String data = HttpUtils.post("http://www.xinvalue.com/v2/api/getFeeling.ashx"
  14.                         params); 
  15.                 JSONArray feels = new JSONArray(data); 
  16.  
  17.                 for (int j = 0; j < feels.length(); j++) { 
  18.                     JSONObject obj = (JSONObject) feels.get(i); 
  19.                     if (obj.getString("_post_content").equals( 
  20.                             selItem.getText().toString())) { 
  21.                         postId = obj.getString("kindId"); 
  22.                         break
  23.                     } 
  24.                 } 
  25.  
  26.             } catch (Exception e) { 
  27.                 e.printStackTrace(); 
  28.             } 
  29.  
  30.             // System.out.println(kindId); 
  31.  
  32.             Intent intent = new Intent(); 
  33.             intent.setClass(FeelActivity.this, FeelDetailActivity.class); 
  34.             Bundle bundle = new Bundle(); // 创建Bundle对象 
  35.             bundle.putString("postId", postId); // 装入数据 
  36.             intent.putExtras(bundle); // 把Bundle塞入Intent里面 
  37.             startActivity(intent); // 开始切换 
  38.         } 
  39.     } 
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2676, '888-2', 'Android中ListView绑定数据三步走', '2013-10-03 04:42:32', '2019-03-25 21:29:22', '

第一步:

定义变量:

  1. private ListView list_feel = null
  2. private List<String> ls_feel = null
  3. private String[] ls_data = {"默认数据"}; 
  4. private ArrayAdapter<String> ad_data = null

第二步:

找到ListView的ID

  1. list_feel=(ListView)findViewById(R.id.list_feel); 

第三步:

获取数据并赋值

  1. String data = HttpUtils.post("http://www.xinvalue.com/v2/api/getFeeling.ashx"
  2.         params); 
  3. JSONArray feels = new JSONArray(data); 
  4.  
  5. ls_feel = new ArrayList<String>(); 
  6.  
  7. for (int i = 0; i < feels.length(); i++) { 
  8.     JSONObject obj = (JSONObject) feels.get(i); 
  9.     ls_feel.add(obj.getString("_post_content")); 
  10.     Util.showToast(FeelActivity.this, obj.getString("_post_content")); 
  11. // 将List抓换为数组 
  12. ls_data = (String[]) ls_feel.toArray(new String[ls_feel.size()]); 
  13.  
  14. ad_data = new ArrayAdapter<String>(FeelActivity.this
  15.         android.R.layout.simple_expandable_list_item_1, ls_data); 
  16. list_feel.setAdapter(ad_data); 
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2677, 'java-sql-date-initialization', 'java.sql.Date初始化', '2013-10-03 02:14:00', '2019-03-25 21:29:22', '

[copy]java-sql-date-initialization[/copy]

\r\n

代码如下:

\r\n
\r\n
 
\r\n
    \r\n
  1. java.sql.Date post_modified = 
  2. \r\n
  3.  new java.sql.Date(new java.util.Date().getTime()); 
  4. \r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2678, '875', '2013-10-17 15:34:49', '2013-10-03 02:23:10', '2019-03-25 21:29:22', '做自己该做的事。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2679, '874', '2013-10-17 15:34:49', '2013-10-03 01:48:56', '2019-03-25 21:29:22', '有些事情只有做了才能知道有没有可能。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2680, 'asp-net-detects-a-potentially-dangerous-requestquerystring-solution-from-the-client', 'Asp .Net从客户端中检测到有潜在危险的Request.QueryString解决方案', '2013-10-02 11:13:02', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

在Web.config添加以下代码即可

  1. <system.web>    
  2.     <pages validateRequest="false" />    
  3.     <httpRuntime requestValidationMode="2.0" />    
  4. </system.web>    
  5.  
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2681, 'jquery-ajax-can-not-get-data', 'Jquery ajax POST 传递JSON数据后台获取不到', '2013-10-02 10:45:19', '2019-03-25 21:29:22', '

前台Ajax代码:

\r\n
\r\n
    \r\n
  1. $.ajax({  
  2. \r\n
  3.     type: \"POST\",  
  4. \r\n
  5.     url: \"./ajaxAddComment.ashx\",  
  6. \r\n
  7.     dataType: \"text\",  
  8. \r\n
  9.     data: \"author=\" + URLencode($(\"#com-author-<%#((Model.wp_posts) Container.DataItem).ID %>\").val()) + \"&email=\" + URLencode($(\"#com-email-<%#((Model.wp_posts) Container.DataItem).ID %>\").val()) + \"&site=\" + URLencode($(\"#com-site-<%#((Model.wp_posts) Container.DataItem).ID %>\").val()) + \"&content=\" + URLencode(msgContent),  
  10. \r\n
  11.     beforeSend: function(XMLHttpRequest) {},  
  12. \r\n
  13.     success: function(msg) {  
  14. \r\n
  15.         alert(msg);  
  16. \r\n
  17.         sAlert(\"留言结果<br/><span style=\'color:green\'>留言成功,再次点击评论就可以查看啦!</span>\")  
  18. \r\n
  19.     },  
  20. \r\n
  21.     complete: function(XMLHttpRequest, textStatus) {},  
  22. \r\n
  23.     error: function() {  
  24. \r\n
  25.         sAlert(\"留言结果<br/><span style=\'color:green\'>额,留言失败,请去掉危险的特殊字符!</span>\")  
  26. \r\n
  27.     }  
  28. \r\n
  29. }); 
  30. \r\n
\r\n
\r\n

错误的获取方法

\r\n
\r\n
    \r\n
  1. context.Request.QueryString[\"author\"]; 
  2. \r\n
\r\n
\r\n

正确的后台获取方法

\r\n
\r\n
    \r\n
  1. context.Request.Params.Get(\"author\"); 
  2. \r\n
\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2682, '869-2', 'Jquery屏蔽回车键,并添加回车搜索', '2013-10-02 07:45:01', '2019-03-25 21:29:22', '
\r\n

\r\n 代码如下:\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n <!--屏蔽回车键,并添加回车搜索-->  \r\n
  2. \r\n
  3. \r\n         <script type=\"text/javascript\">  \r\n
  4. \r\n
  5. \r\n             var ready = $(document).ready(function() {  \r\n
  6. \r\n
  7. \r\n   \r\n
  8. \r\n
  9. \r\n                 $(\"#s\").keypress(function(event) { //屏蔽Enter键  \r\n
  10. \r\n
  11. \r\n                     if (event.keyCode == 13) {  \r\n
  12. \r\n
  13. \r\n                         window.location.href = \"/search.aspx?kw=\" + URLencode($(\"#s\").val());  \r\n
  14. \r\n
  15. \r\n                         return false;  \r\n
  16. \r\n
  17. \r\n                     }  \r\n
  18. \r\n
  19. \r\n                     return true;  \r\n
  20. \r\n
  21. \r\n                 });  \r\n
  22. \r\n
  23. \r\n             });  \r\n
  24. \r\n
  25. \r\n         </script>  \r\n
  26. \r\n
\r\n
\r\n
\r\n
\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2683, '867-2', 'js随机整数', '2013-10-01 14:41:48', '2019-03-25 21:29:22', '

\r\n

\r\n

\r\n 代码如下:\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n function randomInt(x1,x2)  \r\n
  2. \r\n
  3. \r\n {  \r\n
  4. \r\n
  5. \r\n var min_int = parseInt(x1);  \r\n
  6. \r\n
  7. \r\n var max_int = parseInt(x2);  \r\n
  8. \r\n
  9. \r\n if ( isNaN(min_int) || isNaN(max_int) )  \r\n
  10. \r\n
  11. \r\n {  \r\n
  12. \r\n
  13. \r\n alert(\'parameter error\');  \r\n
  14. \r\n
  15. \r\n return false;  \r\n
  16. \r\n
  17. \r\n }  \r\n
  18. \r\n
  19. \r\n   \r\n
  20. \r\n
  21. \r\n x1 = Math.min(min_int,max_int);  \r\n
  22. \r\n
  23. \r\n x2 = Math.max(min_int,max_int);  \r\n
  24. \r\n
  25. \r\n   \r\n
  26. \r\n
  27. \r\n return x1 + Math.floor(Math.random() * (x2 - x1 + 1));  \r\n
  28. \r\n
  29. \r\n }  \r\n
  30. \r\n
\r\n
\r\n
\r\n
\r\n

\r\n

\r\n 用法:var i = randomInt(1,100); var j = randomInt(\'100abc\',\'1000cd\');\r\n

\r\n

\r\n 解析:首先将传过来的参数转化为整型,防止了传过来的参数是字符串的情况,这在直接将页面上的元素的值作为参数的情况下很有用。比如以下:\r\n

\r\n

\r\n var v1 = document.getElementById(\'ele1\').value;\r\n

\r\n

\r\n var v2 = document.getElementById(\'ele2\').value;\r\n

\r\n

\r\n var i = randomInt(v1,v2);\r\n

\r\n

\r\n 因为从页面获得的值是字符串的格式,所以函数先进行了一些判断操作。\r\n

\r\n

\r\n Math.random()-返回0~1之间的一个随机的小数,不包含0和1;\r\n

\r\n

\r\n js取整\r\n

\r\n

\r\n js取整分为3种情况:\r\n

\r\n

\r\n Math.ceil(x)-向上取整,如x=5.1取整为6,x=5.8也取整为6;\r\n

\r\n

\r\n Math.floor(x)-向下取整,如x=5.1取整为5,x=5.8也取整为5;\r\n

\r\n

\r\n Math.round(x)-四舍五入取整,如x=5.1取整为5,x=5.8取整为6;\r\n

\r\n

\r\n Math对象的其他函数:\r\n

\r\n

\r\n Math.abs(x)-取绝对值,如x=-1去为1,x=0取0,x=1取1;\r\n

\r\n

\r\n Math.pow(x,y)-取X的Y次幂,如x=10,y=2,则返回10的2次方,100;\r\n

\r\n

\r\n Math.sqrt(x)-取平方根,如x=25,则返回5;\r\n

\r\n

\r\n Math.min(x,y)-取最小值,返回X,Y中的小的数,如x=3,y=5则返回3;\r\n

\r\n

\r\n Math.max(x,y)-去最大值,返回X,Y中的大的数,如x=3,y=5则返回5;\r\n

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2684, '866-2', 'Jquery配合json和Ajax无刷新评论框', '2013-10-01 14:00:35', '2019-03-25 21:29:22', '

\r\n 代码如下:\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n <span style=\"color: red; cursor: pointer\" id=\"cm-<%#((Model.wp_posts) Container.DataItem).ID %>\">  \r\n
  2. \r\n
  3. \r\n     <span>  \r\n
  4. \r\n
  5. \r\n         评论  \r\n
  6. \r\n
  7. \r\n     </span>  \r\n
  8. \r\n
  9. \r\n     <span>  \r\n
  10. \r\n
  11. \r\n         (  \r\n
  12. \r\n
  13. \r\n         <%#((Model.wp_posts) Container.DataItem).comment_count %>  \r\n
  14. \r\n
  15. \r\n             )  \r\n
  16. \r\n
  17. \r\n     </span>  \r\n
  18. \r\n
  19. \r\n </span>  \r\n
  20. \r\n
  21. \r\n <script type=\"text/javascript\">  \r\n
  22. \r\n
  23. \r\n     var cmid = \"cm-<%#((Model.wp_posts) Container.DataItem).ID %>\";  \r\n
  24. \r\n
  25. \r\n     var sta = false;  \r\n
  26. \r\n
  27. \r\n   \r\n
  28. \r\n
  29. \r\n     $(\"#\" + cmid).click(function() {  \r\n
  30. \r\n
  31. \r\n         if (!sta) {  \r\n
  32. \r\n
  33. \r\n             $(\"#commont-box-\" + <%# ((Model.wp_posts) Container.DataItem).ID % >).show(\"slow\");  \r\n
  34. \r\n
  35. \r\n             sta = true;  \r\n
  36. \r\n
  37. \r\n   \r\n
  38. \r\n
  39. \r\n             // commentAjax();  \r\n
  40. \r\n
  41. \r\n             var objson = \"\"; // [{ \"_comment_agent\": \"Mozilla\r\n/5.0 (Windows NT 5.1; rv:23.0) Gecko/20100101 Firefox\r\n/23.0\", \"_comment_approved\": \"1\", \"_comment_author\": \"admin\", \"_comment_author_email\": \"cyutyw@126.com\", \"_comment_author_ip\": \"127.0.0.1\", \"_comment_author_url\": \"\", \"_comment_content\": \"\r\n呵呵呵!\", \"_comment_date\": \"/Date(1380591991000+0800)\r\n/\", \"_comment_date_gmt\": \"/Date(1380563191000+0800)\r\n/\", \"_comment_id\": 15, \"_comment_karma\": 0, \"_comment_parent\": 0, \"_comment_post_id\": 979, \"_comment_type\": \"\", \"_user_id\": 1 }, { \"_comment_agent\": \"Mozilla\r\n/5.0 (Windows NT 5.1; rv:23.0) Gecko/20100101 Firefox\r\n/23.0\", \"_comment_approved\": \"1\", \"_comment_author\": \"admin\", \"_comment_author_email\": \"cyutyw@126.com\", \"_comment_author_ip\": \"127.0.0.1\", \"_comment_author_url\": \"\", \"_comment_content\": \"\r\n对的,不错 啊哈哈哈哈哈哈哈\", \"_comment_date\": \"/Date(1380603188000+0800)\r\n/\", \"_comment_date_gmt\": \"/Date(1380574388000+0800)/\", \"_comment_id\": 16, \"_comment_karma\": 0, \"_comment_parent\": 0, \"_comment_post_id\": 979, \"_comment_type\": \"\", \"_user_id\": 1 }];  \r\n
  42. \r\n
  43. \r\n             $.ajax({  \r\n
  44. \r\n
  45. \r\n                 type: \"GET\",  \r\n
  46. \r\n
  47. \r\n                 url: \"./ajaxComments.ashx\",  \r\n
  48. \r\n
  49. \r\n                 dataType: \"json\",  \r\n
  50. \r\n
  51. \r\n                 data: \"pid=\" + \"<%#((Model.wp_posts) Container.DataItem).ID %>\",  \r\n
  52. \r\n
  53. \r\n                 beforeSend: function(XMLHttpRequest) {  \r\n
  54. \r\n
  55. \r\n                     //alert(\"异步之前\");  \r\n
  56. \r\n
  57. \r\n                 },  \r\n
  58. \r\n
  59. \r\n                 success: function(msg) {  \r\n
  60. \r\n
  61. \r\n                     objson = msg;  \r\n
  62. \r\n
  63. \r\n                     //  alert(objson);  \r\n
  64. \r\n
  65. \r\n                     $.each(objson,  \r\n
  66. \r\n
  67. \r\n                     function(i, n) {  \r\n
  68. \r\n
  69. \r\n                         //评论附加  \r\n
  70. \r\n
  71. \r\n                         $(\"<div class=\'cmt-item\'>\" + n._comment_content + \"</div>\").appendTo($(\"#\" + \"common-content-<%#((Model.wp_posts) Container.DataItem).ID %>\"));  \r\n
  72. \r\n
  73. \r\n                     });  \r\n
  74. \r\n
  75. \r\n                 },  \r\n
  76. \r\n
  77. \r\n                 complete: function(XMLHttpRequest, textStatus) {  \r\n
  78. \r\n
  79. \r\n                     // alert(\"异步完成!\");  \r\n
  80. \r\n
  81. \r\n                 },  \r\n
  82. \r\n
  83. \r\n                 error: function() {  \r\n
  84. \r\n
  85. \r\n                     alert(\"异步传输错误!\");  \r\n
  86. \r\n
  87. \r\n                 }  \r\n
  88. \r\n
  89. \r\n             });  \r\n
  90. \r\n
  91. \r\n   \r\n
  92. \r\n
  93. \r\n         } else {  \r\n
  94. \r\n
  95. \r\n             $(\"#\" + \"common-content-<%#((Model.wp_posts) Container.DataItem).ID %> div\").remove();  \r\n
  96. \r\n
  97. \r\n             $(\"#commont-box-\" + <%# ((Model.wp_posts) Container.DataItem).ID % >).hide(\"fast\");  \r\n
  98. \r\n
  99. \r\n             sta = false;  \r\n
  100. \r\n
  101. \r\n         }  \r\n
  102. \r\n
  103. \r\n         // alert(\"ok\");  \r\n
  104. \r\n
  105. \r\n     });  \r\n
  106. \r\n
  107. \r\n </script>  \r\n
  108. \r\n
  109. \r\n <!--评论框-->  \r\n
  110. \r\n
  111. \r\n <div id=\"commont-box-<%#((Model.wp_posts) Container.DataItem).ID %>\" style=\"display: none\">  \r\n
  112. \r\n
  113. \r\n     <div id=\"common-content-<%#((Model.wp_posts) Container.DataItem).ID %>\">  \r\n
  114. \r\n
  115. \r\n     </div>  \r\n
  116. \r\n
  117. \r\n     <div>  \r\n
  118. \r\n
  119. \r\n         <div>  \r\n
  120. \r\n
  121. \r\n             <input type=\"text\" value=\"匿名\" />  \r\n
  122. \r\n
  123. \r\n         </div>  \r\n
  124. \r\n
  125. \r\n         <div>  \r\n
  126. \r\n
  127. \r\n             <input type=\"text\" value=\"cyutyw@sina.com\" />  \r\n
  128. \r\n
  129. \r\n         </div>  \r\n
  130. \r\n
  131. \r\n         <div>  \r\n
  132. \r\n
  133. \r\n             <input type=\"text\" value=\"http://www.xinvalue.com\" />  \r\n
  134. \r\n
  135. \r\n         </div>  \r\n
  136. \r\n
  137. \r\n     </div>  \r\n
  138. \r\n
  139. \r\n     <div class=\"express\">  \r\n
  140. \r\n
  141. \r\n         <img src=\"./wbFiles/bg_qcenter_top.jpg\" style=\"width: 20px; height: 20px;\"  \r\n
  142. \r\n
  143. \r\n         />  \r\n
  144. \r\n
  145. \r\n     </div>  \r\n
  146. \r\n
  147. \r\n     <textarea style=\"width: 400px; height: 300px;\">  \r\n
  148. \r\n
  149. \r\n         这是默认的评论内容  \r\n
  150. \r\n
  151. \r\n     </textarea>  \r\n
  152. \r\n
  153. \r\n     <input id=\"com-post-<%#((Model.wp_posts) Container.DataItem).ID %>\" type=\"button\"  \r\n
  154. \r\n
  155. \r\n     value=\"提交评论\" />  \r\n
  156. \r\n
  157. \r\n </div>  \r\n
  158. \r\n
  159. \r\n <!---->  \r\n
  160. \r\n
  161. \r\n <script type=\"text/javascript\">  \r\n
  162. \r\n
  163. \r\n     var subId = \"com-post-<%#((Model.wp_posts) Container.DataItem).ID %>\";  \r\n
  164. \r\n
  165. \r\n     $(\"#\" + subId).click(function() {  \r\n
  166. \r\n
  167. \r\n         //关闭平评论框  \r\n
  168. \r\n
  169. \r\n         $(\"#commont-box-\" + <%# ((Model.wp_posts) Container.DataItem).ID % >).hide(\"slow\");  \r\n
  170. \r\n
  171. \r\n         sAlert(\"评论<br/><span style=\'color:green;\'>恭喜您!效果还不错评论成功!请再次点击评论查看!</span>\");  \r\n
  172. \r\n
  173. \r\n         // alert(\"评论完毕!\");  \r\n
  174. \r\n
  175. \r\n     });  \r\n
  176. \r\n
  177. \r\n </script> 
    \r\n
    \r\n
  178. \r\n
\r\n
\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2685, '862-2', 'jquery遍历JSON数据', '2013-10-01 12:51:20', '2019-03-25 21:29:22', '

\r\n 代码如下:\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n <script type=\"text/javascript\">  \r\n
  2. \r\n
  3. \r\n var objson =[  \r\n
  4. \r\n
  5. \r\n     {  \r\n
  6. \r\n
  7. \r\n         \"_comment_agent\"\"Mozilla/5.0 (Windows NT 5.1; rv:23.0) Gecko/20100101 Firefox/23.0\",  \r\n
  8. \r\n
  9. \r\n         \"_comment_approved\"\"1\",  \r\n
  10. \r\n
  11. \r\n         \"_comment_author\"\"admin\",  \r\n
  12. \r\n
  13. \r\n         \"_comment_author_email\"\"cyutyw@126.com\",  \r\n
  14. \r\n
  15. \r\n         \"_comment_author_ip\"\"127.0.0.1\",  \r\n
  16. \r\n
  17. \r\n         \"_comment_author_url\"\"\",  \r\n
  18. \r\n
  19. \r\n         \"_comment_content\"\"呵呵呵!\",  \r\n
  20. \r\n
  21. \r\n         \"_comment_date\"\"/Date(1380591991000+0800)/\",  \r\n
  22. \r\n
  23. \r\n         \"_comment_date_gmt\"\"/Date(1380563191000+0800)/\",  \r\n
  24. \r\n
  25. \r\n         \"_comment_id\": 15,  \r\n
  26. \r\n
  27. \r\n         \"_comment_karma\": 0,  \r\n
  28. \r\n
  29. \r\n         \"_comment_parent\": 0,  \r\n
  30. \r\n
  31. \r\n         \"_comment_post_id\": 979,  \r\n
  32. \r\n
  33. \r\n         \"_comment_type\"\"\",  \r\n
  34. \r\n
  35. \r\n         \"_user_id\": 1  \r\n
  36. \r\n
  37. \r\n     },  \r\n
  38. \r\n
  39. \r\n     {  \r\n
  40. \r\n
  41. \r\n         \"_comment_agent\"\"Mozilla/5.0 (Windows NT 5.1; rv:23.0) Gecko/20100101 Firefox/23.0\",  \r\n
  42. \r\n
  43. \r\n         \"_comment_approved\"\"1\",  \r\n
  44. \r\n
  45. \r\n         \"_comment_author\"\"admin\",  \r\n
  46. \r\n
  47. \r\n         \"_comment_author_email\"\"cyutyw@126.com\",  \r\n
  48. \r\n
  49. \r\n         \"_comment_author_ip\"\"127.0.0.1\",  \r\n
  50. \r\n
  51. \r\n         \"_comment_author_url\"\"\",  \r\n
  52. \r\n
  53. \r\n         \"_comment_content\"\"对的,不错 啊哈哈哈哈哈哈哈\",  \r\n
  54. \r\n
  55. \r\n         \"_comment_date\"\"/Date(1380603188000+0800)/\",  \r\n
  56. \r\n
  57. \r\n         \"_comment_date_gmt\"\"/Date(1380574388000+0800)/\",  \r\n
  58. \r\n
  59. \r\n         \"_comment_id\": 16,  \r\n
  60. \r\n
  61. \r\n         \"_comment_karma\": 0,  \r\n
  62. \r\n
  63. \r\n         \"_comment_parent\": 0,  \r\n
  64. \r\n
  65. \r\n         \"_comment_post_id\": 979,  \r\n
  66. \r\n
  67. \r\n         \"_comment_type\"\"\",  \r\n
  68. \r\n
  69. \r\n         \"_user_id\": 1  \r\n
  70. \r\n
  71. \r\n     }  \r\n
  72. \r\n
  73. \r\n ];  \r\n
  74. \r\n
  75. \r\n  $.each(objson, function(i, n) {      \r\n
  76. \r\n
  77. \r\n alert(n._comment_author);    \r\n
  78. \r\n
  79. \r\n });     \r\n
  80. \r\n
  81. \r\n </script> 
    \r\n
    \r\n
  82. \r\n
\r\n
\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2686, '857-2', 'jquery如何删除子元素', '2013-10-01 11:48:16', '2019-03-25 21:29:22', '
\r\n
\r\n

\r\n 代码如下:
\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n $(\"div span:gt(0)\").remove(); 
    \r\n
    \r\n
  2. \r\n
\r\n
\r\n
\r\n
\r\n
\r\n解释:
\r\n
    \r\n
  • \r\n

    \r\n gt是大于的意思,0其实代表的就是1\r\n

    \r\n
  • \r\n
  • \r\n

    \r\n remove从字眼上看就知道是去除的意思了。\r\n

    \r\n
  • \r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2687, '854', '2013-10-17 15:34:49', '2013-09-30 20:10:55', '2019-03-25 21:29:22', '定积分连续且单调,有3种方法证明1 把积分限化成相同 2 转换成积分上限的函数,单调性求解 3 用函数单调性放缩证明', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2688, '853', '2013-10-17 15:34:49', '2013-09-30 19:07:20', '2019-03-25 21:29:22', '现在开始,把101%的时间用在复习和思考上,其它一切都不能阻挡。有时候发现,其实我是被自己打败的。这一次,我要改变。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2689, '851-2', 'Wordpress非常有用的SQL语句', '2013-09-30 08:23:53', '2019-03-25 21:29:22', '\r\n

\r\n 1.查询所有的分类目录:\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n SELECT t.*, tt.* FROM wp_terms AS t   \r\n
  2. \r\n
  3. \r\n INNER JOIN wp_term_taxonomy   \r\n
  4. \r\n
  5. \r\n AS tt ON t.term_id = tt.term_id WHERE tt.taxonomy IN (\'category\')   \r\n
  6. \r\n
  7. \r\n ORDER BY t.name ASC 
    \r\n
    \r\n
  8. \r\n
\r\n
\r\n
\r\n
\r\n

\r\n 2.查询指定分类(例如分类别名为feeling)\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n SELECT wp_term_taxonomy.term_id FROM wp_term_taxonomy   \r\n
  2. \r\n
  3. \r\n INNER JOIN wp_terms USING (term_id)   \r\n
  4. \r\n
  5. \r\n WHERE taxonomy = \'category\' AND wp_terms.slug IN (\'feeling\') 
    \r\n
    \r\n
  6. \r\n
\r\n
\r\n
\r\n

\r\n 3.查询指定分类下的文章(例如查询心情随笔)\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n SELECT SQL_CALC_FOUND_ROWS wp_posts. *  \r\n
  2. \r\n
  3. \r\n FROM wp_posts  \r\n
  4. \r\n
  5. \r\n INNER JOIN wp_term_relationships ON ( wp_posts.ID = wp_term_relationships.object_id )  \r\n
  6. \r\n
  7. \r\n WHERE 1 =1  \r\n
  8. \r\n
  9. \r\n AND (  \r\n
  10. \r\n
  11. \r\n wp_term_relationships.term_taxonomy_id  \r\n
  12. \r\n
  13. \r\n IN ( 16 )  \r\n
  14. \r\n
  15. \r\n )  \r\n
  16. \r\n
  17. \r\n AND wp_posts.post_type = \'post\'  \r\n
  18. \r\n
  19. \r\n AND (  \r\n
  20. \r\n
  21. \r\n wp_posts.post_status = \'publish\'  \r\n
  22. \r\n
  23. \r\n OR wp_posts.post_status = \'private\'  \r\n
  24. \r\n
  25. \r\n )  \r\n
  26. \r\n
  27. \r\n GROUP BY wp_posts.ID  \r\n
  28. \r\n
  29. \r\n ORDER BY wp_posts.post_date DESC  \r\n
  30. \r\n
  31. \r\n LIMIT 0 , 10 
    \r\n
    \r\n
  32. \r\n
\r\n
\r\n
\r\n

\r\n
\r\n

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2690, '849', '2013-10-17 15:34:49', '2013-09-30 02:38:17', '2019-03-25 21:29:22', '理科思维是过程的集合,不是结果的集合。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2691, '848', '2013-10-17 15:34:49', '2013-09-30 02:21:14', '2019-03-25 21:29:22', '知识从来不会自己找上门的。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2692, '845', '20131215044914', '2013-09-28 09:12:15', '2019-03-25 21:29:22', '厚积而薄发。\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2693, 'intellij-idea-develop-cpp', 'IntelliJ IDEA开发C 的配置', '2013-09-27 21:32:14', '2019-03-25 21:29:22', '
[member]ghjyhjkyhkj[/member]\r\n\r\n
本文最后更新于2014年1月22日,已超过半年没有更新,如果文章内容失效,请反馈给我们,谢谢!
\r\n\r\n\r\n\r\n一:准备工作\r\n============\r\n下载\r\n----\r\n(1)下载并安装MinGW,安装过程很长要耐心等待,如果你不想安装也可以下载笔者安装好的版本,直接解压即可。\r\n[download id=\"5\"]\r\n\r\n(2)安装IntelliJ IDEA并下载IntelliJ IDEA的C 插件。\r\n[download id=\"6\"]\r\n这里笔者下载的是最新的0.8 build 5。\r\n\r\n安装\r\n----\r\n安装过程也很简单,直接点击Setting-Plugins-Install plugin from disk,找到下载好的CppTools.zip,点击OK,然后点击Apply,重启IntelliJ IDEA。\r\n\r\n二:配置(这个过程要特别注意,笔者之前走了很多弯路)。\r\n===================================================================\r\n\r\n1.MinGW环境变量配置\r\n\r\n(1)右键计算机-属性-高级系统属性-环境变量,加入如下环境变量\r\n\r\n**path **\r\n\r\n**C:\\Soft\\MinGW\\bin;**\r\n\r\n**(PS:如果path有内容,注意在前面加上分号)**\r\n[![5](http://bcs.duapp.com/terwer/5_thumb.png \"5\")](http://bcs.duapp.com/terwer/5.png)\r\n\r\n**C_INCLUDEDE_PATH**\r\n\r\n**C:\\Soft\\MinGW\\include**\r\n\r\n[![6](http://bcs.duapp.com/terwer/6_thumb.png \"6\")](http://bcs.duapp.com/terwer/6.png)\r\n\r\n**CPLUS_INCLUDE_PATH**\r\n\r\n**C:\\Soft\\MinGW\\include**\r\n\r\n[![7](http://bcs.duapp.com/terwer/7_thumb.png \"7\")](http://bcs.duapp.com/terwer/7.png)\r\n\r\n可以打开cmd,输入gcc -v和g -v,测试是否成功:\r\n\r\n[![8](http://bcs.duapp.com/terwer/8_thumb.png \"8\")](http://bcs.duapp.com/terwer/8.png)\r\n\r\n(2)打开IntelliJ IDEA,在IDE Settings里面找到C/C ,修改如下\r\n\r\nPath to Gcc :\r\n\r\n**C:\\Soft\\MinGW\\bin\\gcc.exe**\r\n\r\nPath to Gdb :\r\n\r\n**C:\\Soft\\MinGW\\bin\\gdb.exe**\r\n\r\n点击OK,至此已经离成功不远了。\r\n\r\n三:建项目并配置。\r\n==================\r\n\r\n步骤一,创建C 模块。\r\n---------------------\r\n\r\n选择New-
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2694, 'terwer-so-feture', '新价值网搜索改版啦,输入关键字等待一秒有惊喜哦', '2013-09-26 23:47:56', '2019-03-25 21:29:22', '搜索地址\r\n\r\nhttp://www.terwer.com/search/?blog\r\n\r\n视频搜索地址\r\n\r\nhttp://www.terwer.com/search/\r\n\r\n \r\n\r\n \r\n\r\n ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2695, '840-2', 'escape加号被过滤解决方法', '2013-09-26 23:21:12', '2019-03-25 21:29:22', '

\r\n 今天我在写新价值网搜索时,遇到了见郁闷的事,我用从前台显示页面传字符串变量给处理页面,出现了件怪事,我想传的内容是C++,但接收以后用 输出是C  空格。反复测试好几遍,都是这个结果,真是令人郁闷。\r\n

\r\n

\r\n \"\"
\r\n
\r\n

\r\n

\r\n 在网上搜了搜,找到了原因。\r\n

\r\n原因: url中有些字符被转义,比如空格被编码成加号,于是传的参数明明是加号,获取的值却成了空格。如何解决呢?如果是通过url传递参数,应该对其进行必要的编码。
\r\n

\r\n 解决办法:\r\n

\r\n

\r\n

\r\n 在javascript中加入\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n function URLencode(sStr) {  \r\n
  2. \r\n
  3. \r\n            return escape(sStr).replace(/+/g, \'%2B\').replace(/\"/g, \'%22\').replace(/\'/g, \'%27\').replace(///g, \'%2F\');  \r\n
  4. \r\n
  5. \r\n        } 
    \r\n
    \r\n
  6. \r\n
\r\n
\r\n
\r\n\r\n

\r\n

\r\n \r\n

\r\n 然后对字符串进行处理,如:\r\n

\r\nvar str=URLencode(\"C++\");\r\n

\r\n

\r\n 问题解决后:\r\n

\r\n

\r\n \"\"
\r\n
\r\n

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2696, '839', '20131215044844', '2013-09-26 19:45:03', '2019-03-25 21:29:22', '每个人的经精力都有限,只有在限定的时间里做最重要的事,才是王道。\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2697, '835-2', 'C# json与object相互转换', '2013-09-25 23:14:15', '2019-03-25 21:29:22', '

\r\n Json字符与Json对象的相互转换方式有很多,接下来将为大家介绍一种,感兴趣的朋友可以参考下哈,希望可以帮助到你。\r\n

\r\n

\r\n

\r\n 代码如下:\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n using System;  \r\n
  2. \r\n
  3. \r\n using System.Text;  \r\n
  4. \r\n
  5. \r\n using System.IO;  \r\n
  6. \r\n
  7. \r\n using System.Runtime.Serialization.Json;  \r\n
  8. \r\n
  9. \r\n   \r\n
  10. \r\n
  11. \r\n namespace Utils  \r\n
  12. \r\n
  13. \r\n {  \r\n
  14. \r\n
  15. \r\n     public class JSONHelper  \r\n
  16. \r\n
  17. \r\n     {  \r\n
  18. \r\n
  19. \r\n         /// <summary>  \r\n
  20. \r\n
  21. \r\n         /// 将object类写入json  \r\n
  22. \r\n
  23. \r\n         /// </summary>  \r\n
  24. \r\n
  25. \r\n         /// <typeparam name=\"T\">object具体类型</typeparam>  \r\n
  26. \r\n
  27. \r\n         /// <param name=\"t\">object实例</param>  \r\n
  28. \r\n
  29. \r\n         /// <returns>json字符串</returns>  \r\n
  30. \r\n
  31. \r\n         public static string ToJson<T>(T t)  \r\n
  32. \r\n
  33. \r\n         {  \r\n
  34. \r\n
  35. \r\n             DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof (T));  \r\n
  36. \r\n
  37. \r\n             MemoryStream stream = new MemoryStream();  \r\n
  38. \r\n
  39. \r\n             serializer.WriteObject(stream, t);  \r\n
  40. \r\n
  41. \r\n             String result = Encoding.UTF8.GetString(stream.ToArray());  \r\n
  42. \r\n
  43. \r\n             stream.Close();  \r\n
  44. \r\n
  45. \r\n             return result;  \r\n
  46. \r\n
  47. \r\n         }  \r\n
  48. \r\n
  49. \r\n   \r\n
  50. \r\n
  51. \r\n         /// <summary>  \r\n
  52. \r\n
  53. \r\n         /// 从json读取object  \r\n
  54. \r\n
  55. \r\n         /// </summary>  \r\n
  56. \r\n
  57. \r\n         /// <typeparam name=\"T\">object具体类型</typeparam>  \r\n
  58. \r\n
  59. \r\n         /// <param name=\"strJson\">json字符串</param>  \r\n
  60. \r\n
  61. \r\n         /// <returns>object具体类型</returns>  \r\n
  62. \r\n
  63. \r\n         public static T FromJson<T>(string strJson) where T : class  \r\n
  64. \r\n
  65. \r\n         {  \r\n
  66. \r\n
  67. \r\n             DataContractJsonSerializer ds = new DataContractJsonSerializer(typeof (T));  \r\n
  68. \r\n
  69. \r\n             MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(strJson));  \r\n
  70. \r\n
  71. \r\n             return ds.ReadObject(ms) as T;  \r\n
  72. \r\n
  73. \r\n         }  \r\n
  74. \r\n
  75. \r\n     }  \r\n
  76. \r\n
  77. \r\n
    \r\n
    \r\n
  78. \r\n
\r\n
\r\n
\r\n

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2698, '818-2', 'Repeater绑定List的写法', '2013-09-24 06:46:46', '2019-03-25 21:29:22', '\r\n

\r\n Repeater绑定List的写法(前台)\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n <%#((Model.wp_posts) Container.DataItem).post_title %> 
    \r\n
    \r\n
  2. \r\n
\r\n
\r\n
\r\n\r\n

\r\n Repeater绑定List的写法(后台)
\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n  string kw = objKw.ToString();  \r\n
  2. \r\n
  3. \r\n List<Model.wp_posts> posts = new BLL.Post().GetModelListBySearch(kw, 10);  \r\n
  4. \r\n
  5. \r\n webRepeater.DataSource = posts;  \r\n
  6. \r\n
  7. \r\n webRepeater.DataBind(); 
    \r\n
    \r\n
  8. \r\n
\r\n
\r\n
\r\n
\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2699, 'csharp-connect-mysql', 'C#链接MySql数据库', '2013-09-24 03:06:41', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

\r\n

需要加入MySql.Data.dll,下载地址:可以直接去官网下载:http://dev.mysql.com/downloads/connector/net/
Sql公共类代码(可以将sql语句直接转换成相应的Model和List)

\r\n
\r\n
 
\r\n
    \r\n
  1. using System;     
  2. \r\n
  3. using System.Collections.Generic;     
  4. \r\n
  5. using System.Configuration;     
  6. \r\n
  7. using System.Data;     
  8. \r\n
  9. using System.Reflection;     
  10. \r\n
  11. using MySql.Data.MySqlClient;     
  12. \r\n
  13.  
  14. \r\n
  15. namespace Utils     
  16. \r\n
  17. {     
  18. \r\n
  19.    public class SQLCommon<T> where T : new()     
  20. \r\n
  21.     {     
  22. \r\n
  23.         private static readonly string ConnString = ConfigurationManager.ConnectionStrings[\"ConnMySql\"].ConnectionString;     
  24. \r\n
  25.  
  26. \r\n
  27.         /// <summary>     
  28. \r\n
  29.         /// 根据SQL获取对象实例    
  30. \r\n
  31.          /// </summary>     
  32. \r\n
  33.         /// <param name=\"strSql\"></param>     
  34. \r\n
  35.         /// <param name=\"parameters\"></param>     
  36. \r\n
  37.         /// <returns></returns>     
  38. \r\n
  39.         public static T GetModelBySQL(string strSql, params MySqlParameter[] parameters)     
  40. \r\n
  41.         {     
  42. \r\n
  43.             if (string.IsNullOrEmpty(strSql))     
  44. \r\n
  45.             {     
  46. \r\n
  47.                 return default(T);     
  48. \r\n
  49.             }     
  50. \r\n
  51.  
  52. \r\n
  53.             DataTable dt = MySqlHelper.ExecuteDataset(ConnString, strSql, parameters).Tables[0];     
  54. \r\n
  55.  
  56. \r\n
  57.  
  58. \r\n
  59.             if (dt.Rows.Count != 1)     
  60. \r\n
  61.             {     
  62. \r\n
  63.                 return default(T);     
  64. \r\n
  65.             }     
  66. \r\n
  67.  
  68. \r\n
  69.             T typeModel = new T();    
  70. \r\n
  71.             Type type = typeModel.GetType();     
  72. \r\n
  73.             foreach (DataColumn dc in dt.Columns)     
  74. \r\n
  75.             {     
  76. \r\n
  77.                 if (dt.Rows[0][dc.ColumnName] == System.DBNull.Value)     
  78. \r\n
  79.                 {     
  80. \r\n
  81.                     continue;     
  82. \r\n
  83.                 }     
  84. \r\n
  85.  
  86. \r\n
  87.                 if (type.GetProperty(dc.ColumnName) == null)     
  88. \r\n
  89.                 {     
  90. \r\n
  91.                     continue;     
  92. \r\n
  93.                 }     
  94. \r\n
  95.  
  96. \r\n
  97.                 type.GetProperty(dc.ColumnName).SetValue(typeModel, dt.Rows[0][dc.ColumnName], null);     
  98. \r\n
  99.             }     
  100. \r\n
  101.             return typeModel;     
  102. \r\n
  103.         }     
  104. \r\n
  105.  
  106. \r\n
  107.         /// <summary>     
  108. \r\n
  109.         /// 根据SQL获取对象实例     
  110. \r\n
  111.          /// </summary>     
  112. \r\n
  113.         /// <param name=\"strSql\"></param>     
  114. \r\n
  115.         /// <param name=\"parameters\"></param>     
  116. \r\n
  117.         /// <returns></returns>     
  118. \r\n
  119.         public static List<T> GetModelListBySQL(string strSql, params MySqlParameter[] parameters)     
  120. \r\n
  121.         {    
  122. \r\n
  123.             if (string.IsNullOrEmpty(strSql))     
  124. \r\n
  125.             {     
  126. \r\n
  127.                 return default(List<T>);     
  128. \r\n
  129.            }     
  130. \r\n
  131.  
  132. \r\n
  133.             DataTable dt = MySqlHelper.ExecuteDataset(ConnString, strSql, parameters).Tables[0];     
  134. \r\n
  135.  
  136. \r\n
  137.             //创建一个属性的列表     
  138. \r\n
  139.             List<PropertyInfo> prlist = new List<PropertyInfo>();     
  140. \r\n
  141.  
  142. \r\n
  143.             //获取TResult的类型实例  反射的入口     
  144. \r\n
  145.  
  146. \r\n
  147.             Type t = typeof (T);     
  148. \r\n
  149.             //获得TResult 的所有的Public 属性 并找出TResult属性和DataTable的列名称相同的属性(PropertyInfo) 并加入到属性列表     
  150. \r\n
  151.  
  152. \r\n
  153.             Array.ForEach<PropertyInfo>(t.GetProperties(), p => { if (dt.Columns.IndexOf(p.Name) != -1) prlist.Add(p); });     
  154. \r\n
  155.  
  156. \r\n
  157.             //创建返回的集合     
  158. \r\n
  159.             List<T> oblist = new List<T>();     
  160. \r\n
  161.             foreach (DataRow row in dt.Rows)     
  162. \r\n
  163.             {     
  164. \r\n
  165.                 //创建TResult的实例     
  166. \r\n
  167.                 T ob = new T();     
  168. \r\n
  169.                 //找到对应的数据  并赋值     
  170. \r\n
  171.                 prlist.ForEach(p => { if (row[p.Name] != DBNull.Value) p.SetValue(ob, row[p.Name], null); });     
  172. \r\n
  173.  
  174. \r\n
  175.                 //放入到返回的集合中.     
  176. \r\n
  177.                 oblist.Add(ob);     
  178. \r\n
  179.             }     
  180. \r\n
  181.             return oblist;     
  182. \r\n
  183.         }     
  184. \r\n
  185.     }     
  186. \r\n
  187. }    
  188. \r\n
\r\n

Web.config代码:

\r\n
\r\n
    \r\n
  1. <?xml version=\"1.0\" encoding=\"utf-8\"?> 
  2. \r\n
  3. \r\n
  4. <configuration> 
  5. \r\n
  6.   <system.web> 
  7. \r\n
  8.     <customErrors mode=\"Off\" /> 
  9. \r\n
  10.     <compilation debug=\"true\" targetFramework=\"4.0\" /> 
  11. \r\n
  12.   </system.web> 
  13. \r\n
  14.  
  15. \r\n
  16.   <!--数据库连接字符串--> 
  17. \r\n
  18.   <connectionStrings> 
  19. \r\n
  20.     <add name=\"ConnMySql\" 
  21. \r\n
  22.          connectionString=\"Data Source=localhost;Database=terwer;User Id=root;Password=;charset=utf8\" /> 
  23. \r\n
  24.   </connectionStrings> 
  25. \r\n
  26. \r\n
  27. </configuration> 
  28. \r\n
\r\n
\r\n

使用举例:

\r\n
\r\n
    \r\n
  1. using System;   
  2. \r\n
  3. using System.Collections.Generic;   
  4. \r\n
  5. using System.Linq;   
  6. \r\n
  7. using System.Text;   
  8. \r\n
  9. using MySql.Data.MySqlClient;   
  10. \r\n
  11.    
  12. \r\n
  13. namespace DAL   
  14. \r\n
  15. {   
  16. \r\n
  17.     public class Post   
  18. \r\n
  19.     {   
  20. \r\n
  21.         /// <summary>   
  22. \r\n
  23.         /// 根据id获取一篇文章   
  24. \r\n
  25.         /// </summary>   
  26. \r\n
  27.         /// <param name=\"id\">文章id</param>   
  28. \r\n
  29.         /// <returns>一篇文章信息</returns>   
  30. \r\n
  31.         public Model.wp_posts GetModel(long id)   
  32. \r\n
  33.         {   
  34. \r\n
  35.             return Utils.SQLCommon<Model.wp_posts>.GetModelBySQL(   
  36. \r\n
  37.                 \"SELECT * FROM Wp_Posts WHERE id=@id\", new MySqlParameter(\"id\", id));   
  38. \r\n
  39.         }   
  40. \r\n
  41.    
  42. \r\n
  43.         /// <summary>   
  44. \r\n
  45.         /// 获取num篇文章   
  46. \r\n
  47.         /// </summary>   
  48. \r\n
  49.         /// <param name=\"num\">文章篇数</param>   
  50. \r\n
  51.         /// <returns>指定篇数的文章信息</returns>   
  52. \r\n
  53.         public List<Model.wp_posts> GetModelList(int num)   
  54. \r\n
  55.         {   
  56. \r\n
  57.             return Utils.SQLCommon<Model.wp_posts>.GetModelListBySQL(   
  58. \r\n
  59.                 \"SELECT * FROM Wp_Posts  limit 0,@num\", new MySqlParameter(\"num\", num));   
  60. \r\n
  61.         }   
  62. \r\n
  63.    
  64. \r\n
  65.         /// <summary>   
  66. \r\n
  67.         /// 获取num篇文章   
  68. \r\n
  69.         /// </summary>   
  70. \r\n
  71.         /// /// <param name=\"kw\">关键字</param>   
  72. \r\n
  73.         /// <param name=\"num\">文章篇数</param>   
  74. \r\n
  75.         /// <returns>指定篇数的文章信息</returns>   
  76. \r\n
  77.         public List<Model.wp_posts> GetModelListBySearch(string kw, int num)   
  78. \r\n
  79.         {   
  80. \r\n
  81.    
  82. \r\n
  83.             return Utils.SQLCommon<Model.wp_posts>.GetModelListBySQL(   
  84. \r\n
  85.              String.Format(\"SELECT * FROM Wp_Posts where post_title like \'%{0}%\' or post_content like \'%{0}%\'  limit 0,@num\",kw), new MySqlParameter(\"num\", num));   
  86. \r\n
  87.    
  88. \r\n
  89.             //注意,下面的写法获取不到数据   
  90. \r\n
  91.             //return Utils.SQLCommon<Model.wp_posts>.GetModelListBySQL(   
  92. \r\n
  93.             //      \"SELECT * FROM Wp_Posts where post_title like \'%@kw%\'  or post_content like \'%@kw%\' limit 0,@num\", new MySqlParameter(\"kw\",kw),new MySqlParameter(\"num\", num));   
  94. \r\n
  95.         }   
  96. \r\n
  97.     }   
  98. \r\n
  99. }   
  100. \r\n
\r\n
\r\n

用到的Model如下:

\r\n
\r\n
    \r\n
  1. using System; 
  2. \r\n
  3.  
  4. \r\n
  5. namespace Model 
  6. \r\n
  7. \r\n
  8.     /// <summary> 
  9. \r\n
  10.     /// wp_posts:实体类(属性说明自动提取数据库字段的描述信息) 
  11. \r\n
  12.     /// </summary> 
  13. \r\n
  14.     [Serializable] 
  15. \r\n
  16.     public partial class wp_posts 
  17. \r\n
  18.     { 
  19. \r\n
  20.         public wp_posts() 
  21. \r\n
  22.         { 
  23. \r\n
  24.         } 
  25. \r\n
  26.  
  27. \r\n
  28.         #region Model 
  29. \r\n
  30.  
  31. \r\n
  32.         private ulong _id; 
  33. \r\n
  34.         private ulong _post_author = 0; 
  35. \r\n
  36.         private DateTime _post_date = DateTime.Now; 
  37. \r\n
  38.         private DateTime _post_date_gmt = DateTime.Now; 
  39. \r\n
  40.         private string _post_content; 
  41. \r\n
  42.         private string _post_title; 
  43. \r\n
  44.         private string _post_excerpt; 
  45. \r\n
  46.         private string _post_status = \"publish\"
  47. \r\n
  48.         private string _comment_status = \"open\"
  49. \r\n
  50.         private string _ping_status = \"open\"
  51. \r\n
  52.         private string _post_password; 
  53. \r\n
  54.         private string _post_name; 
  55. \r\n
  56.         private string _to_ping; 
  57. \r\n
  58.         private string _pinged; 
  59. \r\n
  60.         private DateTime _post_modified = DateTime.Now; 
  61. \r\n
  62.         private DateTime _post_modified_gmt = DateTime.Now; 
  63. \r\n
  64.         private string _post_content_filtered; 
  65. \r\n
  66.         private ulong _post_parent = 0; 
  67. \r\n
  68.         private string _guid; 
  69. \r\n
  70.         private int _menu_order = 0; 
  71. \r\n
  72.         private string _post_type = \"post\"
  73. \r\n
  74.         private string _post_mime_type; 
  75. \r\n
  76.         private long _comment_count = 0; 
  77. \r\n
  78.  
  79. \r\n
  80.         /// <summary> 
  81. \r\n
  82.         /// auto_increment 
  83. \r\n
  84.         /// </summary> 
  85. \r\n
  86.         public ulong ID 
  87. \r\n
  88.         { 
  89. \r\n
  90.             set { _id = value; } 
  91. \r\n
  92.             get { return _id; } 
  93. \r\n
  94.         } 
  95. \r\n
  96.  
  97. \r\n
  98.         /// <summary> 
  99. \r\n
  100.         ///  
  101. \r\n
  102.         /// </summary> 
  103. \r\n
  104.         public ulong post_author 
  105. \r\n
  106.         { 
  107. \r\n
  108.             set { _post_author = value; } 
  109. \r\n
  110.             get { return _post_author; } 
  111. \r\n
  112.         } 
  113. \r\n
  114.  
  115. \r\n
  116.         /// <summary> 
  117. \r\n
  118.         ///  
  119. \r\n
  120.         /// </summary> 
  121. \r\n
  122.         public DateTime post_date 
  123. \r\n
  124.         { 
  125. \r\n
  126.             set { _post_date = value; } 
  127. \r\n
  128.             get { return _post_date; } 
  129. \r\n
  130.         } 
  131. \r\n
  132.  
  133. \r\n
  134.         /// <summary> 
  135. \r\n
  136.         ///  
  137. \r\n
  138.         /// </summary> 
  139. \r\n
  140.         public DateTime post_date_gmt 
  141. \r\n
  142.         { 
  143. \r\n
  144.             set { _post_date_gmt = value; } 
  145. \r\n
  146.             get { return _post_date_gmt; } 
  147. \r\n
  148.         } 
  149. \r\n
  150.  
  151. \r\n
  152.         /// <summary> 
  153. \r\n
  154.         ///  
  155. \r\n
  156.         /// </summary> 
  157. \r\n
  158.         public string post_content 
  159. \r\n
  160.         { 
  161. \r\n
  162.             set { _post_content = value; } 
  163. \r\n
  164.             get { return _post_content; } 
  165. \r\n
  166.         } 
  167. \r\n
  168.  
  169. \r\n
  170.         /// <summary> 
  171. \r\n
  172.         ///  
  173. \r\n
  174.         /// </summary> 
  175. \r\n
  176.         public string post_title 
  177. \r\n
  178.         { 
  179. \r\n
  180.             set { _post_title = value; } 
  181. \r\n
  182.             get { return _post_title; } 
  183. \r\n
  184.         } 
  185. \r\n
  186.  
  187. \r\n
  188.         /// <summary> 
  189. \r\n
  190.         ///  
  191. \r\n
  192.         /// </summary> 
  193. \r\n
  194.         public string post_excerpt 
  195. \r\n
  196.         { 
  197. \r\n
  198.             set { _post_excerpt = value; } 
  199. \r\n
  200.             get { return _post_excerpt; } 
  201. \r\n
  202.         } 
  203. \r\n
  204.  
  205. \r\n
  206.         /// <summary> 
  207. \r\n
  208.         ///  
  209. \r\n
  210.         /// </summary> 
  211. \r\n
  212.         public string post_status 
  213. \r\n
  214.         { 
  215. \r\n
  216.             set { _post_status = value; } 
  217. \r\n
  218.             get { return _post_status; } 
  219. \r\n
  220.         } 
  221. \r\n
  222.  
  223. \r\n
  224.         /// <summary> 
  225. \r\n
  226.         ///  
  227. \r\n
  228.         /// </summary> 
  229. \r\n
  230.         public string comment_status 
  231. \r\n
  232.         { 
  233. \r\n
  234.             set { _comment_status = value; } 
  235. \r\n
  236.             get { return _comment_status; } 
  237. \r\n
  238.         } 
  239. \r\n
  240.  
  241. \r\n
  242.         /// <summary> 
  243. \r\n
  244.         ///  
  245. \r\n
  246.         /// </summary> 
  247. \r\n
  248.         public string ping_status 
  249. \r\n
  250.         { 
  251. \r\n
  252.             set { _ping_status = value; } 
  253. \r\n
  254.             get { return _ping_status; } 
  255. \r\n
  256.         } 
  257. \r\n
  258.  
  259. \r\n
  260.         /// <summary> 
  261. \r\n
  262.         ///  
  263. \r\n
  264.         /// </summary> 
  265. \r\n
  266.         public string post_password 
  267. \r\n
  268.         { 
  269. \r\n
  270.             set { _post_password = value; } 
  271. \r\n
  272.             get { return _post_password; } 
  273. \r\n
  274.         } 
  275. \r\n
  276.  
  277. \r\n
  278.         /// <summary> 
  279. \r\n
  280.         ///  
  281. \r\n
  282.         /// </summary> 
  283. \r\n
  284.         public string post_name 
  285. \r\n
  286.         { 
  287. \r\n
  288.             set { _post_name = value; } 
  289. \r\n
  290.             get { return _post_name; } 
  291. \r\n
  292.         } 
  293. \r\n
  294.  
  295. \r\n
  296.         /// <summary> 
  297. \r\n
  298.         ///  
  299. \r\n
  300.         /// </summary> 
  301. \r\n
  302.         public string to_ping 
  303. \r\n
  304.         { 
  305. \r\n
  306.             set { _to_ping = value; } 
  307. \r\n
  308.             get { return _to_ping; } 
  309. \r\n
  310.         } 
  311. \r\n
  312.  
  313. \r\n
  314.         /// <summary> 
  315. \r\n
  316.         ///  
  317. \r\n
  318.         /// </summary> 
  319. \r\n
  320.         public string pinged 
  321. \r\n
  322.         { 
  323. \r\n
  324.             set { _pinged = value; } 
  325. \r\n
  326.             get { return _pinged; } 
  327. \r\n
  328.         } 
  329. \r\n
  330.  
  331. \r\n
  332.         /// <summary> 
  333. \r\n
  334.         ///  
  335. \r\n
  336.         /// </summary> 
  337. \r\n
  338.         public DateTime post_modified 
  339. \r\n
  340.         { 
  341. \r\n
  342.             set { _post_modified = value; } 
  343. \r\n
  344.             get { return _post_modified; } 
  345. \r\n
  346.         } 
  347. \r\n
  348.  
  349. \r\n
  350.         /// <summary> 
  351. \r\n
  352.         ///  
  353. \r\n
  354.         /// </summary> 
  355. \r\n
  356.         public DateTime post_modified_gmt 
  357. \r\n
  358.         { 
  359. \r\n
  360.             set { _post_modified_gmt = value; } 
  361. \r\n
  362.             get { return _post_modified_gmt; } 
  363. \r\n
  364.         } 
  365. \r\n
  366.  
  367. \r\n
  368.         /// <summary> 
  369. \r\n
  370.         ///  
  371. \r\n
  372.         /// </summary> 
  373. \r\n
  374.         public string post_content_filtered 
  375. \r\n
  376.         { 
  377. \r\n
  378.             set { _post_content_filtered = value; } 
  379. \r\n
  380.             get { return _post_content_filtered; } 
  381. \r\n
  382.         } 
  383. \r\n
  384.  
  385. \r\n
  386.         /// <summary> 
  387. \r\n
  388.         ///  
  389. \r\n
  390.         /// </summary> 
  391. \r\n
  392.         public ulong post_parent 
  393. \r\n
  394.         { 
  395. \r\n
  396.             set { _post_parent = value; } 
  397. \r\n
  398.             get { return _post_parent; } 
  399. \r\n
  400.         } 
  401. \r\n
  402.  
  403. \r\n
  404.         /// <summary> 
  405. \r\n
  406.         ///  
  407. \r\n
  408.         /// </summary> 
  409. \r\n
  410.         public string guid 
  411. \r\n
  412.         { 
  413. \r\n
  414.             set { _guid = value; } 
  415. \r\n
  416.             get { return _guid; } 
  417. \r\n
  418.         } 
  419. \r\n
  420.  
  421. \r\n
  422.         /// <summary> 
  423. \r\n
  424.         ///  
  425. \r\n
  426.         /// </summary> 
  427. \r\n
  428.         public int menu_order 
  429. \r\n
  430.         { 
  431. \r\n
  432.             set { _menu_order = value; } 
  433. \r\n
  434.             get { return _menu_order; } 
  435. \r\n
  436.         } 
  437. \r\n
  438.  
  439. \r\n
  440.         /// <summary> 
  441. \r\n
  442.         ///  
  443. \r\n
  444.         /// </summary> 
  445. \r\n
  446.         public string post_type 
  447. \r\n
  448.         { 
  449. \r\n
  450.             set { _post_type = value; } 
  451. \r\n
  452.             get { return _post_type; } 
  453. \r\n
  454.         } 
  455. \r\n
  456.  
  457. \r\n
  458.         /// <summary> 
  459. \r\n
  460.         ///  
  461. \r\n
  462.         /// </summary> 
  463. \r\n
  464.         public string post_mime_type 
  465. \r\n
  466.         { 
  467. \r\n
  468.             set { _post_mime_type = value; } 
  469. \r\n
  470.             get { return _post_mime_type; } 
  471. \r\n
  472.         } 
  473. \r\n
  474.  
  475. \r\n
  476.         /// <summary> 
  477. \r\n
  478.         ///  
  479. \r\n
  480.         /// </summary> 
  481. \r\n
  482.         public long comment_count 
  483. \r\n
  484.         { 
  485. \r\n
  486.             set { _comment_count = value; } 
  487. \r\n
  488.             get { return _comment_count; } 
  489. \r\n
  490.         } 
  491. \r\n
  492.  
  493. \r\n
  494.         #endregion Model 
  495. \r\n
  496.     } 
  497. \r\n
  498. \r\n
\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2700, '816-2', 'ASP.NET给ASHX文件传递中文参数', '2013-09-24 02:52:12', '2019-03-25 21:29:22', '

\r\n 编码:\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n /// <summary>      \r\n
  2. \r\n
  3. \r\n /// 用来给ASHX传递的参数进行编码      \r\n
  4. \r\n
  5. \r\n  /// </summary>      \r\n
  6. \r\n
  7. \r\n /// <param name=\"str\"></param>      \r\n
  8. \r\n
  9. \r\n /// <returns></returns>      \r\n
  10. \r\n
  11. \r\n public static string Escape(string str)      \r\n
  12. \r\n
  13. \r\n {      \r\n
  14. \r\n
  15. \r\n     StringBuilder sb = new StringBuilder();      \r\n
  16. \r\n
  17. \r\n     foreach (char c in str)      \r\n
  18. \r\n
  19. \r\n     {      \r\n
  20. \r\n
  21. \r\n         sb.Append((Char.IsLetterOrDigit(c)      \r\n
  22. \r\n
  23. \r\n             || c == \'-\' || c == \'_\' || c == \'\\\'      \r\n
  24. \r\n
  25. \r\n             || c == \'/\' || c == \'.\') ? c.ToString() : Uri.HexEscape(c));      \r\n
  26. \r\n
  27. \r\n     }      \r\n
  28. \r\n
  29. \r\n     return sb.ToString();      \r\n
  30. \r\n
  31. \r\n }   
    \r\n
    \r\n
  32. \r\n
\r\n
\r\n
\r\n

\r\n 解码:\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n /// <summary>      \r\n
  2. \r\n
  3. \r\n /// 用来解码Escape编码后的内容      \r\n
  4. \r\n
  5. \r\n  /// </summary>      \r\n
  6. \r\n
  7. \r\n /// <param name=\"str\"></param>      \r\n
  8. \r\n
  9. \r\n /// <returns></returns>      \r\n
  10. \r\n
  11. \r\n public static string UnEscape(string str)      \r\n
  12. \r\n
  13. \r\n {      \r\n
  14. \r\n
  15. \r\n     StringBuilder sb = new StringBuilder();      \r\n
  16. \r\n
  17. \r\n     int len = str.Length;      \r\n
  18. \r\n
  19. \r\n     int i = 0;      \r\n
  20. \r\n
  21. \r\n     while (i != len)      \r\n
  22. \r\n
  23. \r\n     {      \r\n
  24. \r\n
  25. \r\n         if (Uri.IsHexEncoding(str, i))      \r\n
  26. \r\n
  27. \r\n             sb.Append(Uri.HexUnescape(str, ref i));      \r\n
  28. \r\n
  29. \r\n         else      \r\n
  30. \r\n
  31. \r\n             sb.Append(str[i++]);      \r\n
  32. \r\n
  33. \r\n     }      \r\n
  34. \r\n
  35. \r\n     return sb.ToString();      \r\n
  36. \r\n
  37. \r\n }     
    \r\n
    \r\n
  38. \r\n
\r\n
\r\n
\r\n
\r\n使用:\r\n

\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n string kw = System.Web.HttpContext.Current.Server.UrlDecode(Utils.CommonFunction.UnEscape(context.Request[\"kw\"])); 
    \r\n
    \r\n
  2. \r\n
\r\n
\r\n
\r\n

\r\n
\r\n

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2701, '814', '程序段 FOR i:=1 DOWNTO 1 DO FOR j:=1 TO i DO IF A[j]>A[j+1] THEN A[j]与A[j+1]对换; 其中n为正整数,则最后一句语句频度在最坏条件下是( )', '2013-09-19 22:14:23', '2019-03-25 21:29:22', '

\r\n 程序\r\n

\r\n

\r\n
\r\n

\r\n
    \r\n
  1. \r\n FOR i:=1 DOWNTO 1 DO  \r\n
  2. \r\n
  3. \r\n         FOR j:=1 TO i DO  \r\n
  4. \r\n
  5. \r\n              IF A[j]>A[j+1]  \r\n
  6. \r\n
  7. \r\n                   THEN A[j]与A[j+1]对换; 
    \r\n
    \r\n
  8. \r\n
\r\n\r\n

\r\n
\r\n

\r\n

\r\n 其中n为正整数,则最后一句语句频度在最坏条件下是( )【南京理工大学大学 1998 一、1(2分)】\r\n

\r\n

\r\n \r\n

\r\n

\r\n 【新价值网解析】\r\n

\r\n

\r\n \"\"
\r\n
\r\n

\r\n

\r\n 答案原创作者:terwer,微博:@LeaveBugsAway,未经允许,谢绝转载!
\r\n
\r\n

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2702, '813', '在下面的程序段中,对x的赋值语句的频度为( )。【北京工商大学 2001 一、10(3分)】', '2013-09-19 21:54:50', '2019-03-25 21:29:22', '

\r\n 在下面程序中,对x的赋值语句的频度( )【北京工商大学 2001 一、10(3分)】\r\n

\r\n

\r\n \r\n

\r\n
    \r\n
  1. \r\n FOR i:=1 TO n DO  \r\n
  2. \r\n
  3. \r\n         FOR j:=1 TO n DO  \r\n
  4. \r\n
  5. \r\n              x:=x+1 
    \r\n
    \r\n
  6. \r\n
\r\n

\r\n 【新价值网解析】\r\n

\r\n

\r\n \"\"
\r\n
\r\n

\r\n

\r\n 答案原创作者:terwer,微博:@LeaveBugsAway,未经允许,谢绝转载!
\r\n
\r\n

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2703, '811', '2014计算机考研大纲解析', '2013-09-18 23:06:54', '2019-03-25 21:29:22', '
\r\n \r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2704, '809', '2014数学一考研大纲解析', '2013-09-18 22:27:10', '2019-03-25 21:29:22', '
\r\n \r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2705, '808', '2014政治考研大纲解析', '2013-09-18 22:03:01', '2019-03-25 21:29:22', '
\r\n \r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2706, '2014kyyydg', '2014英语考研大纲解析', '2013-09-18 21:49:20', '2019-03-25 21:29:22', '

\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2707, '802', '定点数学习笔记', '2013-09-14 23:59:52', '2019-03-25 21:29:22', '

\r\n \"\"\r\n

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2708, 'google-app-engine-delete-app', 'Google App Engine删除app的方法', '2013-09-13 15:03:18', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

\r\n

必须先禁用,再删除。删除后你有72小时的“后悔期”,在这段时间里你还可以撤销删除。一旦永久删除,这个程序里所有的内容包括代码、文件和数据都将不可用,而 且任何人以后都不能使用这个应用程序的名称来注册新的程序。禁用、删除的方法:

\r\n

1. 登录https://appengine.google.com/

\r\n

2. 选择你的应用程序

\r\n

3. 在左边的Administration里点击\"Application Settings\"

\r\n

4. 点\"Disable Application Now\"禁用程序

\r\n

5. 点\"Request Permanent Deletion\"申请删除程序

\r\n

此外你可以新建一个空项目做为新版本,上传后删除原先的版本。方法:

\r\n

1. 建立新的空项目

\r\n

2. 修改下面文件中的版本号:

\r\n

(JAVA项目):项目文件夹warWEB-INFappengine-web.xml

\r\n

(Python项目):项目文件夹warWEB-INFapp.yaml

\r\n

3. 部署/上传

\r\n

4. 登录https://appengine.google.com/

\r\n

5. 在左边的Administration里点击\"Versions\"

\r\n

6. 找到旧的版本,然后点右边的Delete。

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2709, '799-2', '关于域名续费和域名过期', '2013-09-13 11:24:44', '2019-03-25 21:29:22', '
\r\n

\r\n 本文转载自:http://www.admin5.net/thread-4369068-1-1.html,略有改动。\r\n

\r\n
\r\n\r\n

\r\n 域名过期多长时间才可以重新注册
\r\n       一般情况我们不主张,让域名过期,重新注册,一来浪费时间,二来浪费精力。而且影响现行网站的访问。所以,尽可能在到期前一个星期内续缴费用,或者 一次多交几年的费用,以保证域名的正常使用。
\r\n       下面介绍下,真的过期了,保护期限的规定。
\r\n       国内域名和国际域名在正常的注册期过后都不会马上删除,会继续有一个保护期。对于已注册了域名的和将要抢注已过期域名的人来说,都要了解和把握这个 保护期限。而且于国内域名和国际域名的管理机构和机制不一样,它们的保护期也是有很大区别。
\r\n       1. 国内域名:中国国家顶级域名(/cn/com.cn)在注册期限已到后有15天的保护期。也就是在第16天凌晨4:30准时删除。在此期间可以正常使用该域 名,并可对该域名进行管理,续费等相关操作。
\r\n       2. 国际域名:(com/net/org等)一般在过期后67天的保护期,过后才会删除。这个过程可以分成3个阶段(30+30+7):
\r\n       A)前30天,原价自动续费期:注册商保留期(第一个月),在域名过期后一个月内可正常使用该域名,并可对该域名进行管理,续费等相关操作,续费域名 不影响使用,续费价格等同与注册价格。
\r\n       B)第31天到60天,赎回期(或叫偿还期)第二个月:在域名过期后的第二个月为域名的赎回期,在此期间域名会被锁定,您无法进行管理,续费和使用, 需要联系注册商赎回域名,赎回费用一般在1500元以上。
\r\n       C)第61到67天,删除期(第三个月起7天),在此期间,您无法对该域名进行任何操作,包括赎回,等待该域名在删除期到期后删除,删除后可以重新注册。
\r\n       强调:过期67天后会被彻底删除
\r\n       所以如果域名过期,一般情况下请您尽快联系服务商续费,以免影响您的使用。
\r\n       域名,一般有8种状态,这8种状态分别是:
\r\n       a.ACTIVE:活动状态。Registry设置;该域名可以Registrar更改;可以续费;至少被指派一个DNS。
\r\n       b.REGISTRY-LOCK:注册局锁定。注册局设置;该域名不可以更改、删除;必须注册局解除此状态才可以注册商更改域名信息;域名可 以续费;如果域名被指派至少一个DNS则可以包含在(域名根服务器)的区域中(可以正常使用)。
\r\n       c.REGISTRY-HOLD:注册局保留。注册局设置;该域名不可以更改、删除;必须注册局解除此状态才可以注册商更改域名信息;域名可 以续费;该域名不包括在(域名根服务器)的区域中(不能正常使用)。
\r\n       d.REGISTRAR-LOCK:注册商锁定。该域名的原始注册商设置;该域名不可以被更改或删除;必须注册商解除此状态才可以更改域名信息;该域名可以续费。该域名包含在(域名根服务器)的区域中(可以正常使用)。
\r\n        e.REGISTRAR-HOLD:注册商保留。该域名的原始注册商设置;该域名不可以被更改或删除;必须注册商解除此状态才可以更改域名信息;该域名可以续费。该域名不包括在(域名根服务器)的区域中(不能正常使用)。
\r\n       f.REDEMPTIONPERIOD:宽限期。当注册商向注册局提出删除域名请求后,注册局将域名设置称此状态,不过,条件是该域名已经注册了5 天以上(如果该域名注册时间不足5天,则立即删除);该域名不包括在(域名根服务器)的区域中(不能正常使用);该域名不可以被更改或清除,只可以被恢 复;任何其他注册商提出对此域名的更改或其他请求都将被拒绝;该状态最多保持30天。
\r\n       g.PENDINGRESTORE:恢复未决。当注册商提出将处于REDEMPTIONPERIOD的域名恢复请求后,注册局设置;该域名包含在 (域名根服务器)的区域中(可以正常使用);注册商提出的更改或任何其他请求都将被拒绝;在7天之内,有注册商向注册局提供必需的恢复文件,如果注册商在 7天之内提供了这些文件,该域名将被置为ACTIVE状态,否则,该域名将重新返回到REDEMPTIONPERIOD状态。
\r\n

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2710, '787', '希尔排序的算法实现', '2013-09-07 00:18:07', '2019-03-25 21:29:22', '

\r\n  希尔排序(Shell Sort)是插入排序的一种。因D.L.Shell于1959年提出而得名。\r\n

\r\n\r\n

\r\n 希尔排序基本思想\r\n

\r\n\r\n

\r\n   基本思想:
\r\n      先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。所有距离为dl的倍数的记录放在同一个组中。先在各组内进行直接插人排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。
\r\n      该方法实质上是一种分组插入方法。\r\n

\r\n\r\n

\r\n 给定实例的shell排序的排序过程\r\n

\r\n\r\n

\r\n      假设待排序文件有10个记录,其关键字分别是:
\r\n         49,38,65,97,76,13,27,49,55,04。
\r\n      增量序列的取值依次为:
\r\n         5,3,1
\r\n      排序过程如\r\n

\r\n\r\n

\r\n \"\"\r\n

\r\n\r\n

\r\n 算法实现\r\n

\r\n\r\n

\r\n 代码结构\r\n

\r\n\r\n

\r\n \"\"\r\n

\r\n\r\n

\r\n Basic.h\r\n

\r\n\r\n
\r\n
\r\n
    \r\n
  1. \r\n /************************************************************************/  \r\n
  2. \r\n
  3. \r\n /* 基 本变量定义                                                                                                                                                              */  \r\n
  4. \r\n
  5. \r\n /************************************************************************/  \r\n
  6. \r\n
  7. \r\n #include <string.h>  \r\n
  8. \r\n
  9. \r\n #include <ctype.h>  \r\n
  10. \r\n
  11. \r\n #include <malloc.h> //malloc()等  \r\n
  12. \r\n
  13. \r\n #include <limits.h> //INT_MAX等  \r\n
  14. \r\n
  15. \r\n #include <stdio.h> //EOF(=^Z或F6),NULL  \r\n
  16. \r\n
  17. \r\n #include <stdlib.h> //atoi()  \r\n
  18. \r\n
  19. \r\n #include <io.h> //eof()  \r\n
  20. \r\n
  21. \r\n #include <math.h> //floor(),ceil(),abs()  \r\n
  22. \r\n
  23. \r\n #include <process.h> //exit()  \r\n
  24. \r\n
  25. \r\n //函数结果状态代码  \r\n
  26. \r\n
  27. \r\n #define TRUE 1  \r\n
  28. \r\n
  29. \r\n #define FALSE 0  \r\n
  30. \r\n
  31. \r\n #define OK 1  \r\n
  32. \r\n
  33. \r\n #define ERROR 0  \r\n
  34. \r\n
  35. \r\n #define INFEASIBLE -1  \r\n
  36. \r\n
  37. \r\n //#define OVERFLOW -2 因为在math.h中已定义OVERFLOW的值为3,故去掉此行  \r\n
  38. \r\n
  39. \r\n typedef int Status; //Status是函数的类型,其值是函数结果状态代码,如OK等  \r\n
  40. \r\n
  41. \r\n typedef int Boolean; //Boolean是布尔类型,其值是TRUE或FALSE  \r\n
  42. \r\n
  43. \r\n   \r\n
  44. \r\n
  45. \r\n //对两个数值型关键字的比较约定为如下的宏定义  \r\n
  46. \r\n
  47. \r\n #define EQ(a,b) ((a)==(b))  \r\n
  48. \r\n
  49. \r\n #define LT(a,b) ((a)<(b))  \r\n
  50. \r\n
  51. \r\n #define LQ(a,b) ((a)<=(b)  \r\n
  52. \r\n
\r\n
\r\n
\r\n\r\n

\r\n SqList.h\r\n

\r\n\r\n
\r\n
\r\n
    \r\n
  1. \r\n /************************************************************************/  \r\n
  2. \r\n
  3. \r\n /* 待排记录的数据类 型                                                                                                                                                       */  \r\n
  4. \r\n
  5. \r\n /************************************************************************/  \r\n
  6. \r\n
  7. \r\n #define MAXSIZE 20 //一个用作示例的小顺序表的最大长度  \r\n
  8. \r\n
  9. \r\n typedef int KeyType; //定义关键字类型为整型  \r\n
  10. \r\n
  11. \r\n typedef struct {  \r\n
  12. \r\n
  13. \r\n     KeyType key; //关键字项  \r\n
  14. \r\n
  15. \r\n     InfoType otherinfo; //其它数据项,具体类型在主程中定义  \r\n
  16. \r\n
  17. \r\n } RedType; //记录类型  \r\n
  18. \r\n
  19. \r\n   \r\n
  20. \r\n
  21. \r\n typedef struct {  \r\n
  22. \r\n
  23. \r\n     RedType r[MAXSIZE + 1]; //r[0]闲置或用作哨兵单元  \r\n
  24. \r\n
  25. \r\n     int length; //顺序表长度  \r\n
  26. \r\n
  27. \r\n } SqList; //顺序表类型  \r\n
  28. \r\n
  29. \r\n   \r\n
  30. \r\n
  31. \r\n /************************************************************************/  \r\n
  32. \r\n
  33. \r\n /* 顺序表插入排序的函数(3个)                                                           */  \r\n
  34. \r\n
  35. \r\n /************************************************************************/  \r\n
  36. \r\n
  37. \r\n   \r\n
  38. \r\n
  39. \r\n //对顺序表L作直接插入排序。算法10.1  \r\n
  40. \r\n
  41. \r\n void InsertSort(SqList *L) {  \r\n
  42. \r\n
  43. \r\n     int i, j;  \r\n
  44. \r\n
  45. \r\n     for (i = 2; i <= (*L).length; ++i)  \r\n
  46. \r\n
  47. \r\n         if (LT((*L).r[i].key, (*L).r[i - 1].key)) { //"<",需将L.r[i]插入有序子表  \r\n
  48. \r\n
  49. \r\n             (*L).r[0] = (*L).r[i]; //复制为哨兵  \r\n
  50. \r\n
  51. \r\n             for (j = i - 1; LT((*L).r[0].key, (*L).r[j].key); --j)  \r\n
  52. \r\n
  53. \r\n                 (*L).r[j + 1] = (*L).r[j]; //记录后移  \r\n
  54. \r\n
  55. \r\n             (*L).r[j + 1] = (*L).r[0]; //插入到正确位置  \r\n
  56. \r\n
  57. \r\n         }  \r\n
  58. \r\n
  59. \r\n }  \r\n
  60. \r\n
  61. \r\n   \r\n
  62. \r\n
  63. \r\n //对顺序表L作折半插入排序。算法10.2  \r\n
  64. \r\n
  65. \r\n void BInsertSort(SqList *L) {  \r\n
  66. \r\n
  67. \r\n     int i, j, m, low, high;  \r\n
  68. \r\n
  69. \r\n     for (i = 2; i <= (*L).length; ++i) {  \r\n
  70. \r\n
  71. \r\n         (*L).r[0] = (*L).r[i]; //将L.r[i]暂存到L.r[0]  \r\n
  72. \r\n
  73. \r\n         low = 1;  \r\n
  74. \r\n
  75. \r\n         high = i - 1;  \r\n
  76. \r\n
  77. \r\n         while (low <= high) { //在r[low..high]中折半查找有序插入的位置  \r\n
  78. \r\n
  79. \r\n             m = (low + high) / 2; //折半  \r\n
  80. \r\n
  81. \r\n         if LT((*L).r[0].key,(*L).r[m].key)  \r\n
  82. \r\n
  83. \r\n         high=m-1; //插入点在低半区  \r\n
  84. \r\n
  85. \r\n         else  \r\n
  86. \r\n
  87. \r\n         low=m+1;//插入点在高半区  \r\n
  88. \r\n
  89. \r\n     }  \r\n
  90. \r\n
  91. \r\n     for (j = i - 1; j >= high + 1; --j)  \r\n
  92. \r\n
  93. \r\n         (*L).r[j + 1] = (*L).r[j]; //记录后移  \r\n
  94. \r\n
  95. \r\n     (*L).r[high + 1] = (*L).r[0]; //插入  \r\n
  96. \r\n
  97. \r\n }  \r\n
  98. \r\n
  99. \r\n }  \r\n
  100. \r\n
  101. \r\n   \r\n
  102. \r\n
  103. \r\n  //2_路插入排序  \r\n
  104. \r\n
  105. \r\n void P2_InsertSort(SqList *L) {  \r\n
  106. \r\n
  107. \r\n int i, j, first, final;  \r\n
  108. \r\n
  109. \r\n RedType *d;  \r\n
  110. \r\n
  111. \r\n d = (RedType*) malloc((*L).length * sizeof(RedType)); //生成L.length个记录的临时空间  \r\n
  112. \r\n
  113. \r\n d[0] = (*L).r[1]; //设L的第1个记录为d中排好序的记录(在位置[0])  \r\n
  114. \r\n
  115. \r\n first = final = 0; //first、final分别指示d中排好序的记录的第1个和最后1个记录的位置  \r\n
  116. \r\n
  117. \r\n for (i = 2; i <= (*L).length; ++i) { //依次将L的第2个~最后1个记录插入d中  \r\n
  118. \r\n
  119. \r\n     if ((*L).r[i].key <  d[first].key) { //待插记录小于d中最小值,插到d[first]之前(不需移动d数组的元素)  \r\n
  120. \r\n
  121. \r\n         first = (first - 1 + (*L).length) % (*L).length; //设d为循环向量  \r\n
  122. \r\n
  123. \r\n         d[first] = (*L).r[i];  \r\n
  124. \r\n
  125. \r\n     } else if ((*L).r[i].key > d[final].key) { //待插记录大于d中最大值,插到d[final]之后(不需移动d数组的元素)  \r\n
  126. \r\n
  127. \r\n         final = final + 1;  \r\n
  128. \r\n
  129. \r\n         d[final] = (*L).r[i];  \r\n
  130. \r\n
  131. \r\n     } else { //待插记录大于d中最小值,小于d中最大值,插到d的中间(需要移动d数组的元素)  \r\n
  132. \r\n
  133. \r\n         j = final++; //移动d的尾部元素以便按序插入记录  \r\n
  134. \r\n
  135. \r\n         while ((*L).r[i].key <  d[j].key) {  \r\n
  136. \r\n
  137. \r\n             d[(j + 1) % (*L).length] = d[j];  \r\n
  138. \r\n
  139. \r\n             j = (j - 1 + (*L).length) % (*L).length;  \r\n
  140. \r\n
  141. \r\n         }  \r\n
  142. \r\n
  143. \r\n         d[j + 1] = (*L).r[i];  \r\n
  144. \r\n
  145. \r\n     }  \r\n
  146. \r\n
  147. \r\n }  \r\n
  148. \r\n
  149. \r\n for (i = 1; i <= (*L).length; i++) //把d赋给L.r  \r\n
  150. \r\n
  151. \r\n     (*L).r[i] = d[(i + first - 1) % (*L).length]; //线性关系  \r\n
  152. \r\n
  153. \r\n }  \r\n
  154. \r\n
\r\n
\r\n
\r\n\r\n

\r\n ShellSort.c\r\n

\r\n\r\n
\r\n
\r\n
    \r\n
  1. \r\n /************************************************************************/  \r\n
  2. \r\n
  3. \r\n /* 希尔排 序                                                                                                                                                                       */  \r\n
  4. \r\n
  5. \r\n /************************************************************************/  \r\n
  6. \r\n
  7. \r\n #include <stdio.h>  \r\n
  8. \r\n
  9. \r\n typedef int InfoType; //定义其它数据项的类型  \r\n
  10. \r\n
  11. \r\n #include "Basic.h"  \r\n
  12. \r\n
  13. \r\n #include "SqList.h"  \r\n
  14. \r\n
  15. \r\n   \r\n
  16. \r\n
  17. \r\n //对顺序表L作一趟希尔插入排序。本算法是和一趟直接插入排序相比,  \r\n
  18. \r\n
  19. \r\n //作了以下修改:  \r\n
  20. \r\n
  21. \r\n //1.前后记录位置的增量是dk,而不是1;  \r\n
  22. \r\n
  23. \r\n //2.r[0]只是暂存单元,不是哨兵。当j<=0时,插入位置已找到。算法10.4  \r\n
  24. \r\n
  25. \r\n void ShellInsert(SqList *L, int dk) {  \r\n
  26. \r\n
  27. \r\n     int i, j;  \r\n
  28. \r\n
  29. \r\n     for (i = dk + 1; i <= (*L).length; ++i)  \r\n
  30. \r\n
  31. \r\n         if (LT((*L).r[i].key,(*L).r[i-dk].key)) { //需将(*L).r[i]插入有序增量子表  \r\n
  32. \r\n
  33. \r\n             (*L).r[0] = (*L).r[i]; //暂存在(*L).r[0]  \r\n
  34. \r\n
  35. \r\n             for (j = i - dk; j > 0 && LT((*L).r[0].key,(*L).r[j].key); j -= dk)  \r\n
  36. \r\n
  37. \r\n                 (*L).r[j + dk] = (*L).r[j]; //记录后移,查找插入位置  \r\n
  38. \r\n
  39. \r\n             (*L).r[j + dk] = (*L).r[0]; //插入  \r\n
  40. \r\n
  41. \r\n         }  \r\n
  42. \r\n
  43. \r\n }  \r\n
  44. \r\n
  45. \r\n   \r\n
  46. \r\n
  47. \r\n void print(SqList L) {  \r\n
  48. \r\n
  49. \r\n     int i;  \r\n
  50. \r\n
  51. \r\n     for (i = 1; i <= L.length; i++)  \r\n
  52. \r\n
  53. \r\n         printf("%d ", L.r[i].key);  \r\n
  54. \r\n
  55. \r\n     printf("n");  \r\n
  56. \r\n
  57. \r\n }  \r\n
  58. \r\n
  59. \r\n   \r\n
  60. \r\n
  61. \r\n void print1(SqList L) {  \r\n
  62. \r\n
  63. \r\n     int i;  \r\n
  64. \r\n
  65. \r\n     for (i = 1; i <= L.length; i++)  \r\n
  66. \r\n
  67. \r\n         printf("(%d,%d)", L.r[i].key, L.r[i].otherinfo);  \r\n
  68. \r\n
  69. \r\n     printf("n");  \r\n
  70. \r\n
  71. \r\n }  \r\n
  72. \r\n
  73. \r\n   \r\n
  74. \r\n
  75. \r\n //按增量序列dlta[0..t-1]对顺序表L作希尔排序。算法10.5  \r\n
  76. \r\n
  77. \r\n void ShellSort(SqList *L, int dlta[], int t) {  \r\n
  78. \r\n
  79. \r\n     int k;  \r\n
  80. \r\n
  81. \r\n     for (k = 0; k < t; ++k) {  \r\n
  82. \r\n
  83. \r\n         ShellInsert(L, dlta[k]); //一趟增量为dlta[k]的插入排序  \r\n
  84. \r\n
  85. \r\n         printf("第%d趟排序结果: ", k + 1);  \r\n
  86. \r\n
  87. \r\n         print(*L);  \r\n
  88. \r\n
  89. \r\n     }  \r\n
  90. \r\n
  91. \r\n }  \r\n
  92. \r\n
  93. \r\n   \r\n
  94. \r\n
  95. \r\n #define N 10  \r\n
  96. \r\n
  97. \r\n #define T 3  \r\n
  98. \r\n
  99. \r\n int main() {  \r\n
  100. \r\n
  101. \r\n     setvbuf(stdout, NULL, _IONBF, 0);  \r\n
  102. \r\n
  103. \r\n     RedType d[N] = { { 49, 1 }, { 38, 2 }, { 65, 3 }, { 97, 4 }, { 76, 5 }, {  \r\n
  104. \r\n
  105. \r\n             13, 6 }, { 27, 7 }, { 49, 8 }, { 55, 9 }, { 4, 10 } };  \r\n
  106. \r\n
  107. \r\n     SqList l;  \r\n
  108. \r\n
  109. \r\n     int i, dt[T] = { 5, 3, 1 }; //增量序列数组  \r\n
  110. \r\n
  111. \r\n     for (i = 0; i < N; i++)  \r\n
  112. \r\n
  113. \r\n         l.r[i + 1] = d[i];  \r\n
  114. \r\n
  115. \r\n     l.length = N;  \r\n
  116. \r\n
  117. \r\n     printf("排序前: ");  \r\n
  118. \r\n
  119. \r\n     print(l);  \r\n
  120. \r\n
  121. \r\n     ShellSort(&l, dt, T);  \r\n
  122. \r\n
  123. \r\n     printf("排序后: ");  \r\n
  124. \r\n
  125. \r\n     print1(l);  \r\n
  126. \r\n
  127. \r\n     return 0;  \r\n
  128. \r\n
  129. \r\n }  \r\n
  130. \r\n
\r\n
\r\n
\r\n\r\n

\r\n 运行演示:\r\n

\r\n\r\n

\r\n \"\"\r\n

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2711, '786', '折半插入排序的实现', '2013-09-06 23:02:41', '2019-03-25 21:29:22', '

\r\n 代码如下:\r\n

\r\n\r\n
\r\n
\r\n
    \r\n
  1. \r\n #include <stdio.h>  \r\n
  2. \r\n
  3. \r\n #include <stdlib.h>  \r\n
  4. \r\n
  5. \r\n   \r\n
  6. \r\n
  7. \r\n typedef int KeyType; //定义关键字类型为整型  \r\n
  8. \r\n
  9. \r\n typedef int InfoType;  \r\n
  10. \r\n
  11. \r\n typedef struct {  \r\n
  12. \r\n
  13. \r\n     KeyType key; //关键字项  \r\n
  14. \r\n
  15. \r\n     InfoType otherinfo; //其它数据项,具体类型在主程中定义  \r\n
  16. \r\n
  17. \r\n } RedType; //记录类型  \r\n
  18. \r\n
  19. \r\n   \r\n
  20. \r\n
  21. \r\n typedef RedType ElemType;  \r\n
  22. \r\n
  23. \r\n   \r\n
  24. \r\n
  25. \r\n void InsertSort_Sec(ElemType a[], int n) {  \r\n
  26. \r\n
  27. \r\n     int i, j, low, high, mid;  \r\n
  28. \r\n
  29. \r\n     for (i = 2; i <= n; i++) {  \r\n
  30. \r\n
  31. \r\n         a[0] = a[i];  \r\n
  32. \r\n
  33. \r\n         low = 1, high = i - 1;  \r\n
  34. \r\n
  35. \r\n         while (low <= high) {  \r\n
  36. \r\n
  37. \r\n             mid = (low + high) / 2;  \r\n
  38. \r\n
  39. \r\n             if (a[mid].key > a[0].key)  \r\n
  40. \r\n
  41. \r\n                 high = mid - 1;  \r\n
  42. \r\n
  43. \r\n             else  \r\n
  44. \r\n
  45. \r\n                 low = mid + 1;  \r\n
  46. \r\n
  47. \r\n         }  \r\n
  48. \r\n
  49. \r\n         for (j = i - 1; j >= high + 1; --j)  \r\n
  50. \r\n
  51. \r\n             a[j + 1] = a[j];  \r\n
  52. \r\n
  53. \r\n         a[high + 1] = a[0];  \r\n
  54. \r\n
  55. \r\n     }  \r\n
  56. \r\n
  57. \r\n }  \r\n
  58. \r\n
  59. \r\n   \r\n
  60. \r\n
  61. \r\n void Print(ElemType a[], int n) {  \r\n
  62. \r\n
  63. \r\n     int i;  \r\n
  64. \r\n
  65. \r\n     for (i = 1; i <= n; i++) {  \r\n
  66. \r\n
  67. \r\n         printf("%d ", a[i].key);  \r\n
  68. \r\n
  69. \r\n     }  \r\n
  70. \r\n
  71. \r\n }  \r\n
  72. \r\n
  73. \r\n   \r\n
  74. \r\n
  75. \r\n int main() {  \r\n
  76. \r\n
  77. \r\n     ElemType a[6] =  \r\n
  78. \r\n
  79. \r\n             { { 0, 0 }, { 5, 0 }, { 4, 0 }, { 3, 0 }, { 2, 0 }, { 1, 0 } };  \r\n
  80. \r\n
  81. \r\n     Print(a, 5);  \r\n
  82. \r\n
  83. \r\n     InsertSort_Sec(a, 5);  \r\n
  84. \r\n
  85. \r\n     printf("n");  \r\n
  86. \r\n
  87. \r\n     Print(a, 5);  \r\n
  88. \r\n
  89. \r\n     return 0;  \r\n
  90. \r\n
  91. \r\n }  \r\n
  92. \r\n
\r\n
\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2712, 'ckeditor-remove-format', 'ckeditor编辑器Word文档粘贴自动去格式的解决方法', '2013-09-06 22:21:31', '2019-03-25 21:29:22', '

      在wordpress程序中使用了ckeditor插件,版本升到了最新的3.4.2.0。
      但在程序进行时,对其富文本编辑框中粘贴WORD文档时,格式仍然有丢失现象。
      甚至使用其WORD导入按钮,效果也是一样。
      查网上资料后,终于找到解决方法:
      在config.js中加入以下语句。

\r\n

代码如下:

\r\n
\r\n
    \r\n
  1. CKEDITOR.editorConfig = function( config )  
  2. \r\n
  3. {  
  4. \r\n
  5.       //config.pasteFromWordIgnoreFontFace = true; //默认为忽略格式  
  6. \r\n
  7.       config.pasteFromWordRemoveFontStyles = false;  
  8. \r\n
  9.       config.pasteFromWordRemoveStyles = false;  
  10. \r\n
  11. };  
  12. \r\n
\r\n
\r\n

问题解决。

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2713, 'direct-insertion-sort', '直接插入排序的实现', '2013-09-06 22:02:25', '2019-03-25 21:29:22', '

代码如下

\r\n
[code lang=\"cpp\"]\r\n#include  <stdio.h>\r\n#include  <stdlib.h>\r\n\r\ntypedef int KeyType; //定义关键字类型为整型\r\ntypedef int InfoType;\r\ntypedef struct {\r\n    KeyType key; //关键字项\r\n    InfoType otherinfo; //其它数据项,具体类型在主程中定义\r\n} RedType; //记录类型\r\n\r\ntypedef RedType ElemType;\r\n\r\nvoid InsertSort(ElemType a[], int n) {\r\n    int i = 0, j = 0;\r\n    for (i = 2; i < = n; i++) {\r\n        if (a[i].key <  a[i - 1].key) {\r\n            a[0] = a[i];\r\n            for (j = i - 1; a[0].key <  a[j].key; --j) {\r\n                a[j + 1] = a[j];\r\n            }\r\n            a[j + 1] = a[0];\r\n        }\r\n    }\r\n}\r\n\r\nvoid Print(ElemType a[], int n) {\r\n    int i;\r\n    for (i = 1; i <= n; i++) {\r\n        printf(\"%d \", a[i].key);\r\n    }\r\n}\r\n\r\nint main() {\r\n    ElemType a[6] =\r\n            { { 0, 0 }, { 5, 0 }, { 4, 0 }, { 3, 0 }, { 2, 0 }, { 1, 0 } };\r\n    Print(a, 5);\r\n    InsertSort(a, 5);\r\n    printf(\"n\");\r\n    Print(a, 5);\r\n    return 0;\r\n}\r\n[/code]
\r\n

运行效果

\r\n

\"http://bcs.duapp.com/terwer/images/aaa.jpg\"

\r\n

 

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2714, '782-2', '插入排序的算法实现(C语言)', '2013-09-06 20:36:32', '2019-03-25 21:29:22', '

\r\n 代码结构:\r\n

\r\n

\r\n \"\"\r\n

\r\n

\r\n \r\n

\r\n Basic.h\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n /************************************************************************/  \r\n
  2. \r\n
  3. \r\n /* 基本变量定义                                                          */  \r\n
  4. \r\n
  5. \r\n /************************************************************************/  \r\n
  6. \r\n
  7. \r\n #include <string.h>  \r\n
  8. \r\n
  9. \r\n #include <ctype.h>  \r\n
  10. \r\n
  11. \r\n #include <malloc.h> //malloc()等  \r\n
  12. \r\n
  13. \r\n #include <limits.h> //INT_MAX等   \r\n
  14. \r\n
  15. \r\n #include <stdio.h> //EOF(=^Z或F6),NULL   \r\n
  16. \r\n
  17. \r\n #include <stdlib.h> //atoi()   \r\n
  18. \r\n
  19. \r\n #include <io.h> //eof()   \r\n
  20. \r\n
  21. \r\n #include <math.h> //floor(),ceil(),abs()   \r\n
  22. \r\n
  23. \r\n #include <process.h> //exit()   \r\n
  24. \r\n
  25. \r\n //函数结果状态代码   \r\n
  26. \r\n
  27. \r\n #define TRUE 1  \r\n
  28. \r\n
  29. \r\n #define FALSE 0  \r\n
  30. \r\n
  31. \r\n #define OK 1  \r\n
  32. \r\n
  33. \r\n #define ERROR 0  \r\n
  34. \r\n
  35. \r\n #define INFEASIBLE -1  \r\n
  36. \r\n
  37. \r\n //#define OVERFLOW -2 因为在math.h中已定义OVERFLOW的值为3,故去掉此行   \r\n
  38. \r\n
  39. \r\n typedef int Status; //Status是函数的类型,其值是函数结果状态代码,如OK等   \r\n
  40. \r\n
  41. \r\n typedef int Boolean; //Boolean是布尔类型,其值是TRUE或FALSE   \r\n
  42. \r\n
  43. \r\n   \r\n
  44. \r\n
  45. \r\n //对两个数值型关键字的比较约定为如下的宏定义  \r\n
  46. \r\n
  47. \r\n #define EQ(a,b) ((a)==(b))  \r\n
  48. \r\n
  49. \r\n #define LT(a,b) ((a)<(b))  \r\n
  50. \r\n
  51. \r\n #define LQ(a,b) ((a)<=(b) 
    \r\n
    \r\n
  52. \r\n
\r\n
\r\n
\r\n

\r\n SqList.h\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n /************************************************************************/  \r\n
  2. \r\n
  3. \r\n /*待排记录的数据类型                                                                     */                                                                       \r\n
  4. \r\n
  5. \r\n /************************************************************************/  \r\n
  6. \r\n
  7. \r\n  #define MAXSIZE 20 //一个用作示例的小顺序表的最大长度   \r\n
  8. \r\n
  9. \r\n  typedef int KeyType; //定义关键字类型为整型   \r\n
  10. \r\n
  11. \r\n  typedef struct{  \r\n
  12. \r\n
  13. \r\n    KeyType key; //关键字项   \r\n
  14. \r\n
  15. \r\n    InfoType otherinfo; //其它数据项,具体类型在主程中定义   \r\n
  16. \r\n
  17. \r\n  }RedType; //记录类型  \r\n
  18. \r\n
  19. \r\n   \r\n
  20. \r\n
  21. \r\n  typedef struct{  \r\n
  22. \r\n
  23. \r\n    RedType r[MAXSIZE+1]; //r[0]闲置或用作哨兵单元   \r\n
  24. \r\n
  25. \r\n    int length; //顺序表长度   \r\n
  26. \r\n
  27. \r\n  }SqList; //顺序表类型   \r\n
  28. \r\n
  29. \r\n   \r\n
  30. \r\n
  31. \r\n  /************************************************************************/  \r\n
  32. \r\n
  33. \r\n /* 顺序表插入排序的函数(3个)                                                           */                                                                       \r\n
  34. \r\n
  35. \r\n /************************************************************************/  \r\n
  36. \r\n
  37. \r\n   \r\n
  38. \r\n
  39. \r\n  //对顺序表L作直接插入排序。算法10.1  \r\n
  40. \r\n
  41. \r\n  void InsertSort(SqList *L){   \r\n
  42. \r\n
  43. \r\n    int i,j;  \r\n
  44. \r\n
  45. \r\n    for(i=2;i<=(*L).length;++i)  \r\n
  46. \r\n
  47. \r\n      if(LT((*L).r[i].key,(*L).r[i-1].key)){//\"<\",需将L.r[i]插入有序子表   \r\n
  48. \r\n
  49. \r\n        (*L).r[0]=(*L).r[i]; //复制为哨兵   \r\n
  50. \r\n
  51. \r\n        for(j=i-1;LT((*L).r[0].key,(*L).r[j].key);--j)  \r\n
  52. \r\n
  53. \r\n      (*L).r[j+1]=(*L).r[j]; //记录后移   \r\n
  54. \r\n
  55. \r\n        (*L).r[j+1]=(*L).r[0]; //插入到正确位置  \r\n
  56. \r\n
  57. \r\n      }  \r\n
  58. \r\n
  59. \r\n  }  \r\n
  60. \r\n
  61. \r\n   \r\n
  62. \r\n
  63. \r\n  //对顺序表L作折半插入排序。算法10.2  \r\n
  64. \r\n
  65. \r\n  void BInsertSort(SqList *L)  \r\n
  66. \r\n
  67. \r\n  {   \r\n
  68. \r\n
  69. \r\n    int i,j,m,low,high;  \r\n
  70. \r\n
  71. \r\n    for(i=2;i<=(*L).length;++i)  \r\n
  72. \r\n
  73. \r\n    {  \r\n
  74. \r\n
  75. \r\n      (*L).r[0]=(*L).r[i]; //将L.r[i]暂存到L.r[0]   \r\n
  76. \r\n
  77. \r\n      low=1;  \r\n
  78. \r\n
  79. \r\n      high=i-1;  \r\n
  80. \r\n
  81. \r\n      while(low<=high)  \r\n
  82. \r\n
  83. \r\n      { //在r[low..high]中折半查找有序插入的位置   \r\n
  84. \r\n
  85. \r\n        m=(low+high)/2; //折半   \r\n
  86. \r\n
  87. \r\n        if LT((*L).r[0].key,(*L).r[m].key)  \r\n
  88. \r\n
  89. \r\n          high=m-1; //插入点在低半区   \r\n
  90. \r\n
  91. \r\n        else  \r\n
  92. \r\n
  93. \r\n          low=m+1; //插入点在高半区  \r\n
  94. \r\n
  95. \r\n      }  \r\n
  96. \r\n
  97. \r\n      for(j=i-1;j>=high+1;--j)  \r\n
  98. \r\n
  99. \r\n        (*L).r[j+1]=(*L).r[j]; //记录后移   \r\n
  100. \r\n
  101. \r\n      (*L).r[high+1]=(*L).r[0]; //插入   \r\n
  102. \r\n
  103. \r\n    }  \r\n
  104. \r\n
  105. \r\n  }  \r\n
  106. \r\n
  107. \r\n   \r\n
  108. \r\n
  109. \r\n  //2_路插入排序  \r\n
  110. \r\n
  111. \r\n  void P2_InsertSort(SqList *L)  \r\n
  112. \r\n
  113. \r\n  {   \r\n
  114. \r\n
  115. \r\n    int i,j,first,final;  \r\n
  116. \r\n
  117. \r\n    RedType *d;  \r\n
  118. \r\n
  119. \r\n    d=(RedType*)malloc((*L).length*sizeof(RedType)); //生成L.length个记录的临时空间   \r\n
  120. \r\n
  121. \r\n    d[0]=(*L).r[1]; //设L的第1个记录为d中排好序的记录(在位置[0])   \r\n
  122. \r\n
  123. \r\n    first=final=0; //first、final分别指示d中排好序的记录的第1个和最后1个记录的位置  \r\n
  124. \r\n
  125. \r\n    for(i=2;i<=(*L).length;++i)  \r\n
  126. \r\n
  127. \r\n    { //依次将L的第2个~最后1个记录插入d中   \r\n
  128. \r\n
  129. \r\n      if((*L).r[i].key<d[first].key)  \r\n
  130. \r\n
  131. \r\n      { //待插记录小于d中最小值,插到d[first]之前(不需移动d数组的元素)   \r\n
  132. \r\n
  133. \r\n        first=(first-1+(*L).length)%(*L).length; //设d为循环向量   \r\n
  134. \r\n
  135. \r\n        d[first]=(*L).r[i];  \r\n
  136. \r\n
  137. \r\n      }  \r\n
  138. \r\n
  139. \r\n      else if((*L).r[i].key>d[final].key)  \r\n
  140. \r\n
  141. \r\n      { //待插记录大于d中最大值,插到d[final]之后(不需移动d数组的元素)  \r\n
  142. \r\n
  143. \r\n        final=final+1;  \r\n
  144. \r\n
  145. \r\n        d[final]=(*L).r[i];  \r\n
  146. \r\n
  147. \r\n      }  \r\n
  148. \r\n
  149. \r\n      else  \r\n
  150. \r\n
  151. \r\n      { //待插记录大于d中最小值,小于d中最大值,插到d的中间(需要移动d数组的元素)   \r\n
  152. \r\n
  153. \r\n        j=final++; //移动d的尾部元素以便按序插入记录   \r\n
  154. \r\n
  155. \r\n        while((*L).r[i].key<d[j].key)  \r\n
  156. \r\n
  157. \r\n        {  \r\n
  158. \r\n
  159. \r\n          d[(j+1)%(*L).length]=d[j];  \r\n
  160. \r\n
  161. \r\n          j=(j-1+(*L).length)%(*L).length;  \r\n
  162. \r\n
  163. \r\n        }  \r\n
  164. \r\n
  165. \r\n        d[j+1]=(*L).r[i];  \r\n
  166. \r\n
  167. \r\n      }  \r\n
  168. \r\n
  169. \r\n    }  \r\n
  170. \r\n
  171. \r\n    for(i=1;i<=(*L).length;i++) //把d赋给L.r   \r\n
  172. \r\n
  173. \r\n      (*L).r[i]=d[(i+first-1)%(*L).length]; //线性关系   \r\n
  174. \r\n
  175. \r\n  } 
    \r\n
    \r\n
  176. \r\n
\r\n
\r\n
\r\n

\r\n Main.cpp\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n  /************************************************************************/  \r\n
  2. \r\n
  3. \r\n /*检验插入排序的程序                                                                      */                                                                       \r\n
  4. \r\n
  5. \r\n /************************************************************************/  \r\n
  6. \r\n
  7. \r\n #include \"Basic.h\"  \r\n
  8. \r\n
  9. \r\n  typedef int InfoType; //定义其它数据项的类型   \r\n
  10. \r\n
  11. \r\n #include \"SqList.h\"  \r\n
  12. \r\n
  13. \r\n   \r\n
  14. \r\n
  15. \r\n  void print(SqList L)  \r\n
  16. \r\n
  17. \r\n  {  \r\n
  18. \r\n
  19. \r\n    int i;  \r\n
  20. \r\n
  21. \r\n    for(i=1;i<=L.length;i++)  \r\n
  22. \r\n
  23. \r\n      printf(\"(%d,%d)\",L.r[i].key,L.r[i].otherinfo);  \r\n
  24. \r\n
  25. \r\n    printf(\"n\");  \r\n
  26. \r\n
  27. \r\n  }  \r\n
  28. \r\n
  29. \r\n   \r\n
  30. \r\n
  31. \r\n  #define N 8  \r\n
  32. \r\n
  33. \r\n int main()  \r\n
  34. \r\n
  35. \r\n  {  \r\n
  36. \r\n
  37. \r\n    RedType d[N]={{49,1},{38,2},{65,3},{97,4},{76,5},{13,6},{27,7},{49,8}};  \r\n
  38. \r\n
  39. \r\n    SqList l1,l2,l3;  \r\n
  40. \r\n
  41. \r\n    int i;  \r\n
  42. \r\n
  43. \r\n    for(i=0;i<N;i++) //给l1.r赋值   \r\n
  44. \r\n
  45. \r\n      l1.r[i+1]=d[i];  \r\n
  46. \r\n
  47. \r\n    l1.length=N;  \r\n
  48. \r\n
  49. \r\n    l2=l3=l1; //复制顺序表l2、l3与l1相同   \r\n
  50. \r\n
  51. \r\n    printf(\"排序前:n\");  \r\n
  52. \r\n
  53. \r\n    print(l1);  \r\n
  54. \r\n
  55. \r\n    InsertSort(&l1);  \r\n
  56. \r\n
  57. \r\n    printf(\"直接插入排序后:n\");  \r\n
  58. \r\n
  59. \r\n    print(l1);  \r\n
  60. \r\n
  61. \r\n    BInsertSort(&l2);  \r\n
  62. \r\n
  63. \r\n    printf(\"折半插入排序后:n\");  \r\n
  64. \r\n
  65. \r\n    print(l2);  \r\n
  66. \r\n
  67. \r\n    P2_InsertSort(&l3);  \r\n
  68. \r\n
  69. \r\n    printf(\"2_路插入排序后:n\");  \r\n
  70. \r\n
  71. \r\n    print(l3);  \r\n
  72. \r\n
  73. \r\n    system(\"pause\");  \r\n
  74. \r\n
  75. \r\n    return 0;  \r\n
  76. \r\n
  77. \r\n  } 
    \r\n
    \r\n
  78. \r\n
\r\n
\r\n
\r\n\r\n

\r\n 时间复杂度分析:\r\n

\r\n

\r\n \"\"\r\n

\r\n

\r\n 因此,时间复杂度位o(n2)。\r\n

\r\n

\r\n\r\n

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2718, '777-2', '引用优酷视频屏蔽广告代码', '2013-09-06 01:15:42', '2019-03-25 21:29:22', '

\r\n       经常引用一些视频网站的视频,但前面的广告很让人心烦,一分钟的视频,却看了30秒的广告,有木有?\r\n

\r\n
\r\n
\r\n

\r\n 通过下面的代码引用优酷的视频可以屏蔽掉广告:\r\n

\r\n

\r\n \r\n

\r\n

\r\n 代码预览\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n <p style=\"text-align: center;\">  \r\n
  2. \r\n
  3. \r\n <embed src=http://static.youku.com/v1.0.0149/v/swf/loader.swf?VideoIDS=ID&winType=adshow&isAutoPlay=true\"   \r\n
  4. \r\n
  5. \r\n quality=\"high\" width=\"x\" height=\"y\" align=\"middle\" allowScriptAccess=\"never\"   \r\n
  6. \r\n
  7. \r\n allowNetworking=\"internal\" autostart=\"0\" type=\"application/x-shockwave-flash\">  \r\n
  8. \r\n
  9. \r\n </embed>  \r\n
  10. \r\n
  11. \r\n </p> 
    \r\n
    \r\n
  12. \r\n
\r\n
\r\n
\r\n

\r\n
\r\n

\r\n

\r\n \r\n

\r\n

\r\n
\r\n

\r\n

\r\n 调整是否自动播放:\r\n

\r\n

\r\n isAutoPlay=false(不自动)\r\n

\r\n

\r\n isAutoPlay=true(自动播放)\r\n

\r\n

\r\n 调整大小:\r\n

\r\n

\r\n width=\"x\"height=\"Y\"\r\n

\r\n

\r\n 常见几种比例:\r\n

\r\n

\r\n 384×256、580×435、610×460\r\n

\r\n

\r\n 替换视频地址:\r\n

\r\n

\r\n 红色部分是URL链接中视频的ID,比如:\r\n

\r\n

\r\n \r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n http://v.youku.com/v_show/id_XMTU5ODYxMzI0.html  \r\n
  2. \r\n
\r\n
\r\n
\r\n用链接中的XMTU5ODYxMzI0,替换红色部分即可。\r\n

\r\n
\r\n

\r\n

\r\n 采用以上的方法,就能够将优酷视频前面的广告屏蔽掉,比如下面的视频:\r\n

\r\n
\r\n
\r\n
\r\n

\r\n 上面的视频插入代码:\r\n

\r\n

\r\n \r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n  <p style=\"text-align: center;\">    \r\n
  2. \r\n
  3. \r\n <embed src=http://static.youku.com/v1.0.0149/v/swf/loader.swf?VideoIDS=XMTU5ODYxMzI0&winType=adshow&isAutoPlay=true\"   \r\n
  4. \r\n
  5. \r\n quality=\"high\" width=\"600\" height=\"480\" align=\"middle\" allowScriptAccess=\"never\"   \r\n
  6. \r\n
  7. \r\n allowNetworking=\"internal\" autostart=\"0\" type=\"application/x-shockwave-flash\">  \r\n
  8. \r\n
  9. \r\n </embed>  \r\n
  10. \r\n
  11. \r\n </p>   
    \r\n
    \r\n
  12. \r\n
\r\n
\r\n
\r\n

\r\n \r\n

\r\n

\r\n 大家试试吧!\r\n

\r\n

\r\n PS:其实,还有更简单的办法,只需插入Flash,然后地址写上\r\n

\r\n

\r\n \r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n http://static.youku.com/v1.0.0149/v/swf/loader.swf?VideoIDS=XMTU5ODYxMzI0&winType=adshow&isAutoPlay=true 
    \r\n
    \r\n
  2. \r\n
\r\n
\r\n
\r\n

\r\n 即可。(将其中的ID换掉就行了)\r\n

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2719, '774-2', 'js复制某一个div的内容(不支持Firefox)', '2013-09-05 23:37:01', '2019-03-25 21:29:22', '
\r\n

\r\n HTML 预览\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n <script type=\"text/javascript\">  \r\n
  2. \r\n
  3. \r\n  function copyToClipboard() {    \r\n
  4. \r\n
  5. \r\n     try {    \r\n
  6. \r\n
  7. \r\n         var txt = document.getElementById(\"divLog\").innerText;    \r\n
  8. \r\n
  9. \r\n         window.clipboardData.setData(\'text\', txt);    \r\n
  10. \r\n
  11. \r\n         alert(\'复制成功,请使用\"Ctrl+V\"粘贴!\');    \r\n
  12. \r\n
  13. \r\n     } catch (e) {   \r\n
  14. \r\n
  15. \r\n         alert(\'对不起,您的浏览器不支持复制,请自行复制!\');    \r\n
  16. \r\n
  17. \r\n     }    \r\n
  18. \r\n
  19. \r\n }    \r\n
  20. \r\n
  21. \r\n  </script>  \r\n
  22. \r\n
  23. \r\n <input type=\"button\" value=\"点击复制\" onclick=\"copyToClipboard();\" />  \r\n
  24. \r\n
  25. \r\n <div id=\"divLog\">  \r\n
  26. \r\n
  27. \r\n 这里是复制的内容  \r\n
  28. \r\n
  29. \r\n </div>  \r\n
  30. \r\n
\r\n
\r\n
\r\n
\r\n

\r\n 演示:\r\n

\r\n

\r\n \"\"
\r\n
\r\n

\r\n

\r\n
\r\n

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2720, '772', '光滑圆盘面上有一质量为m的物体A,拴在一根穿过圆盘中心O处光滑小孔的细绳上,如图所示.开始时,该物体距圆盘中心O的距离为r0,并以角速度w0绕盘心O作圆周运动.现向下拉绳,当质点A的径向距离由r0减少到 时,向下拉的速度为v,求下拉过程中拉力所作的功.', '2013-09-05 17:12:30', '2019-03-25 21:29:22', '\"\"', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2721, '771', '有一质量为m1、长为l的均匀细棒,静止平放在滑动摩擦系数为u的水平桌面上,它可绕通过其端点O且与桌面垂直的固定光滑轴转动.另有一水平运动的质量为m2的小滑块,从侧面垂直于棒与棒的另一端A相碰撞,设碰撞时间极短.已知小滑块在碰撞前后的速度分别为 和 ,如图所示.求碰撞后从细棒开始转动到停止转动的过程所需的时间.(已知棒绕O点的转动惯量J=m1l2/3)', '2013-09-05 16:14:56', '2019-03-25 21:29:22', '\"\"', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2722, '770', '质量分别为m和2m、半径分别为r和2r的两个均匀圆盘,同轴地粘在一起,可以绕通过盘心且垂直盘面的水平光滑固定轴转动,对转轴的转动惯量为9mr2 / 2,大小圆盘边缘都绕有绳子,绳子下端都挂一质量为m的重物,如图所示.求盘的角加速度的大小.', '2013-09-05 16:03:37', '2019-03-25 21:29:22', '\"\"', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2723, '769', '质量为2 kg的质点,按方程 (SI)沿着x轴振动.求: (1) t = 0时,作用于质点的力的大小; (2)作用于质点的力的最大值和此时质点的位置.', '2013-09-05 16:00:02', '2019-03-25 21:29:22', '\"\"', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2724, '1309040637', '质量为m、长为l的棒,可绕通过棒中心且与棒垂直的竖直光滑固定轴O在水平面内自由转动(转动惯量J=m l 2 / 12).开始时棒静止,现有一子弹,质量也是m,在水平面内以速度v 0垂直射入棒端并嵌在其中.则子弹嵌入后棒的角速度w=_____________________.', '2013-09-04 14:37:03', '2019-03-25 21:29:22', '

题目

\"\" 

答案

本题应用角动量守恒法。

子弹射入前,体系的总角动量为

\"dpi{300}

子弹射入后,体系的总角动量为

\"dpi{300}

\"\"

因为无外力矩,故体系角动量守恒

\"dpi{300}

\"dpi{300}

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2725, '760', '转动着的飞轮的转动惯量为J,在t=0时角速度为w 0.此后飞轮经历制动过程.阻力矩M的大小与角速度w 的平方成正比,比例系数为k (k为大于0的常量).当w=w0/3时,飞轮的角加速度b = __________.从开始制动到w=w0/3所经过的时间t=_______________.', '2013-09-04 13:35:44', '2019-03-27 02:41:37', '

\r\n 题目:
\r\n\r\n

\r\n

\r\n \"\"
\r\n
\r\n

\r\n

\r\n 答案:\r\n

\r\n

\r\n 由转动定理可得:\r\n

\r\n

\r\n \"\"\r\n

\r\n

\r\n 由动量矩定理可得:\r\n

\r\n

\r\n \"\"
\r\n\r\n

\r\n

\r\n
\r\n
\r\n

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2726, '759', '20131215044820', '2013-09-04 10:17:18', '2019-03-25 21:29:22', '把握每一天,在有限的时间里做最需要的事!\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2727, '705-2', 'CKEditor加入中文字体', '2013-09-02 13:01:45', '2019-03-25 21:29:22', '

\r\n \r\n

\r\n

\r\n
\r\n

\r\n
\r\n 本文转载自:http://www.cnblogs.com/ndxsdhy/archive/2010/12/07/1899408.html,略有改动。\r\n
\r\n\r\n

\r\n
\r\n

\r\n

\r\n       今天,ckeditor迎来了十周年。笔者第一次使用ckeditor时2012年,一直感觉不错。\r\n

\r\n

\r\n \"\"
\r\n
\r\n

\r\n

\r\n       CKEditor确实非常好,但是编辑时,字体选择里面没有中文字体\"\",可以按如下方法添加,打开CKeditor目录里的config.js,修改如下\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n CKEDITOR.editorConfig = function(config) {  \r\n
  2. \r\n
  3. \r\n         //加入中文    \r\n
  4. \r\n
  5. \r\n         config.font_names=\'宋体/宋体;黑体/黑体;仿宋/仿宋_GB2312;  \r\n
  6. \r\n
  7. \r\n 楷体/楷体_GB2312;隶书/隶书;幼圆/幼圆;微软雅黑/微软雅黑;\'  \r\n
  8. \r\n
  9. \r\n + config.font_names;   \r\n
  10. \r\n
  11. \r\n };  \r\n
  12. \r\n
\r\n
\r\n
\r\n

\r\n       以后使用的时候就可以用中文字体了,呵呵\"\"\r\n

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2728, 'wordpress-disappear-you-want-to', 'wordpress发布新页面出现“您确定要这样做?请重试。”解决方法', '2013-09-01 22:05:40', '2019-03-25 21:29:22', '

 

\r\n
\r\n

本文转载自:http://www.discuz.net/thread-3443265-1-1.html,略有改动。

\r\n

小编拿到客户后台的权限,也进去尝试了一下,发表页面确实会出现这个情况。在仔细了解了客户对哪里做了修改之后,无忧主机小编得到了一个这样的情 况:由于客户在wordpress上安装了百度编辑器,安装过程中有这样一个步骤:将wp-admin/edit-form-advanced.php进 行了替换。

\r\n

在得知这一情况之后,小编想,如果是安装百度编辑器造成的问题,那么把以上文件替换回来,是不是就能够解决问题呢?

\r\n

小编拿到客户的空间信息,并在网上下载了一个客户同版本的wordpress,用其中的wp-admin目录下的edit-form-advanced.php替换掉了客户空间的文件,然后进行了新建页面的测试。果然,网站恢复了正常。

\r\n

这个问题,是客户使用百度编辑器出的问题。小编也在网上找了一下相关的问题,发现,用百度编辑器造成这个问题的还真不在少数。无忧主机小编也在这里提醒一 下大家,编辑器尽量使用本地的编辑器,在空间安装的话,容易出现问题。如果大家遇到了类似的问题,可以用小编今天的方法试试,应该能够解决。

\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2730, '581', '树状数组', '2013-08-12 21:53:14', '2019-03-25 21:29:22', '

\r\n      如果给定一个数组,要你求里面所有数的和,一般都会想到累加。但是当那个数组很大的时候,累加就显得太耗时了,时间复杂度为O(n),并且采用累加的方法还有一个局限,那就是,当修改掉数组中的元素后,仍然要你求数组中某段元素的和,就显得麻烦了。所以我们就要用到树状数组,他的时间复杂度为O(lgn),相比之下就快得多。下面就讲一下什么是树状数组:\r\n

\r\n

\r\n      一般讲到树状数组都会少不了下面这个图: 
\r\n
\r\n

\r\n

\r\n \"\"
\r\n
\r\n

\r\n

\r\n      下面来分析一下上面那个图看能得出什么规律:\r\n

\r\n

\r\n      据图可知:     c1=a1,c2=a1+a2,c3=a3,c4=a1+a2+a3+a4,c5=a5,c6=a5+a6,c7=a7,c8=a1+a2+a3+a4+a5+a6+a7+a8,c9=a9,c10=a9+a10,c11=a11........c16=a1+a2+a3+a4+a5+.......+a16。\r\n

\r\n

\r\n       分析上面的几组式子可知,当 i 为奇数时,ci=ai ;当 i 为偶数时,就要看 i 的因子中最多有二的多少次幂,例如,6 的因子中有 2 的一次幂,等于 2 ,所以 c6=a5+a6(由六向前数两个数的和),4 的因子中有 2 的两次幂,等于 4 ,所以 c4=a1+a2+a3+a4(由四向前数四个数的和)。\r\n

\r\n

\r\n      (一)有公式:cn=a(n-a^k+1)+.........+an(其中 k 为 n 的二进制表示中从右往左数的 0 的个数)。\r\n

\r\n

\r\n      那么,如何求 a^k 呢?求法如下:\r\n

\r\n

\r\n \r\n

\r\n
\r\n

\r\n 求a^k
\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n int lowbit(int x){  \r\n
  2. \r\n
  3. \r\n      return x&(-x);   \r\n
  4. \r\n
  5. \r\n
    \r\n
    \r\n
  6. \r\n
\r\n
\r\n
\r\n
\r\n

\r\n
\r\n

\r\n
\r\n
\r\n         lowbit()的返回值就是 2^k 次方的值。\r\n
\r\n
\r\n

\r\n         求出来 2^k 之后,数组 c 的值就都出来了,接下来我们要求数组中所有元素的和。\r\n

\r\n

\r\n         (二)求数组的和的算法如下:\r\n

\r\n

\r\n         (1)首先,令sum=0,转向第二步;\r\n

\r\n

\r\n         (2)接下来判断,如果 n>0 的话,就令sum=sum+cn转向第三步,否则的话,终止算法,返回 sum 的值;\r\n

\r\n

\r\n         (3)n=n - lowbit(n)(将n的二进制表示的最后一个零删掉),回第二步。\r\n

\r\n

\r\n \r\n

\r\n

\r\n 代码实现\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n int Sum(int n){    \r\n
  2. \r\n
  3. \r\n     int sum=0;    \r\n
  4. \r\n
  5. \r\n     while(n>0){    \r\n
  6. \r\n
  7. \r\n          sum+=c[n];    \r\n
  8. \r\n
  9. \r\n          n=n-lowbit(n);    \r\n
  10. \r\n
  11. \r\n     }       \r\n
  12. \r\n
  13. \r\n     return sum;    \r\n
  14. \r\n
  15. \r\n }   
    \r\n
    \r\n
  16. \r\n
\r\n
\r\n
\r\n
\r\n\r\n

\r\n

\r\n \r\n

\r\n
\r\n
\r\n         (三)当数组中的元素有变更时,树状数组就发挥它的优势了,算法如下(修改为给某个节点 i 加上 x ):\r\n
\r\n
\r\n

\r\n         (1)当 i<=n 时,执行下一步;否则的话,算法结束;\r\n

\r\n

\r\n         (2)ci=ci+x ,i=i+lowbit(i)(在 i 的二进制表示的最后加零),返回第一步。\r\n

\r\n

\r\n \r\n

\r\n
\r\n

\r\n 代码实现\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n void change(int i,int x){  \r\n
  2. \r\n
  3. \r\n      while(i<=n){  \r\n
  4. \r\n
  5. \r\n           c[i]=c[i]+x;  \r\n
  6. \r\n
  7. \r\n           i=i+lowbit(i);  \r\n
  8. \r\n
  9. \r\n      }  \r\n
  10. \r\n
  11. \r\n }  \r\n
  12. \r\n
\r\n
\r\n
\r\n
\r\n
\r\n

\r\n
\r\n

\r\n
\r\n

\r\n
\r\n\r\n

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2731, '574', '试分别画出具有3个结点的树和3个结点的二叉树的所有不同形态。', '2013-08-08 21:16:33', '2019-03-25 21:29:22', '

\r\n \"\"\r\n

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2732, 'xv-get-in-c-2', '用C语言写的迅雷看看XV文件提取器及C语言源代码', '2013-07-19 19:08:25', '2019-03-25 21:29:22', '

\r\n 【版权声明:本文转载自http://www.cnblogs.com/nbsofer/archive/2012/08/18/2645979.html,版权归原作者。如需转载,请务必在转载时注明原文地址。】\r\n

\r\n

\r\n \r\n

\r\n

\r\n 代码如下:\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n /* \r\n
  2. \r\n
  3. \r\n tabsize:4 \r\n
  4. \r\n
  5. \r\n */  \r\n
  6. \r\n
  7. \r\n #include <stdio.h>  \r\n
  8. \r\n
  9. \r\n #include <string.h>  \r\n
  10. \r\n
  11. \r\n #define _WIN32_WINNT 0x0502  \r\n
  12. \r\n
  13. \r\n #include <Windows.h>  \r\n
  14. \r\n
  15. \r\n   \r\n
  16. \r\n
  17. \r\n int cntFileProcessed = 0;    //count file that processed, accumulated.  \r\n
  18. \r\n
  19. \r\n int scrWidth;                //screen width  \r\n
  20. \r\n
  21. \r\n   \r\n
  22. \r\n
  23. \r\n void ResetCursorPos(void)  \r\n
  24. \r\n
  25. \r\n {  \r\n
  26. \r\n
  27. \r\n     CONSOLE_SCREEN_BUFFER_INFO sbi;  \r\n
  28. \r\n
  29. \r\n     COORD co;  \r\n
  30. \r\n
  31. \r\n     HANDLE hOutput;  \r\n
  32. \r\n
  33. \r\n     hOutput = GetStdHandle(STD_OUTPUT_HANDLE);  \r\n
  34. \r\n
  35. \r\n     GetConsoleScreenBufferInfo(hOutput, &sbi);  \r\n
  36. \r\n
  37. \r\n     co.X = sbi.dwCursorPosition.X-(5+1+4);    //e.g.:1024M,100%  \r\n
  38. \r\n
  39. \r\n     co.Y = sbi.dwCursorPosition.Y;  \r\n
  40. \r\n
  41. \r\n     SetConsoleCursorPosition(hOutput, co);  \r\n
  42. \r\n
  43. \r\n     //sure to leave hOutput as it was  \r\n
  44. \r\n
  45. \r\n     return;      \r\n
  46. \r\n
  47. \r\n }  \r\n
  48. \r\n
  49. \r\n   \r\n
  50. \r\n
  51. \r\n void ExtractFile(char* filespec)  \r\n
  52. \r\n
  53. \r\n {  \r\n
  54. \r\n
  55. \r\n #define BUFSIZE ((1<<20)*5)    //5M buffer  \r\n
  56. \r\n
  57. \r\n     HANDLE hFileIn = NULL;    //handle of input file  \r\n
  58. \r\n
  59. \r\n     HANDLE hFileOut = NULL;    //handle of output file  \r\n
  60. \r\n
  61. \r\n   \r\n
  62. \r\n
  63. \r\n     DWORD dwSizeRead = 0;    //the ReadFile function Read size  \r\n
  64. \r\n
  65. \r\n     DWORD dwSizeWritten = 0;//the WriteFile function Written size  \r\n
  66. \r\n
  67. \r\n     DWORD dwSize = 0;  \r\n
  68. \r\n
  69. \r\n       \r\n
  70. \r\n
  71. \r\n     int magicNumber = 0;    //you may know when you look, I suppose.  \r\n
  72. \r\n
  73. \r\n     int fileType = 0;        //indicates what file it is  \r\n
  74. \r\n
  75. \r\n   \r\n
  76. \r\n
  77. \r\n     LARGE_INTEGER li;        //for SetFilePointer function use,2M offset of REAL movie data  \r\n
  78. \r\n
  79. \r\n   \r\n
  80. \r\n
  81. \r\n     BYTE hdr[4];            //the *.xv file header  \r\n
  82. \r\n
  83. \r\n     BYTE ch;                //  \r\n
  84. \r\n
  85. \r\n     char* pchar;            //tmp use  \r\n
  86. \r\n
  87. \r\n     char fileOut[MAX_PATH];    //namely, the output file  \r\n
  88. \r\n
  89. \r\n     BYTE* buffer = NULL;    //block extraction data, every time it extracts 5MB data at most  \r\n
  90. \r\n
  91. \r\n   \r\n
  92. \r\n
  93. \r\n     char* errMsg = NULL;    //FormatMessage  \r\n
  94. \r\n
  95. \r\n     int lastErr = 0;        //GetLastError  \r\n
  96. \r\n
  97. \r\n   \r\n
  98. \r\n
  99. \r\n     int percent = 0;        //percentage of processed data  \r\n
  100. \r\n
  101. \r\n     int readSize = 0;        //total size Read  \r\n
  102. \r\n
  103. \r\n     DWORD fileSize;            //total file size, for percentage use  \r\n
  104. \r\n
  105. \r\n   \r\n
  106. \r\n
  107. \r\n     int prtLen;                //the printf(and its relative) returned  \r\n
  108. \r\n
  109. \r\n     int dotLen;                //as you see at the screen  \r\n
  110. \r\n
  111. \r\n   \r\n
  112. \r\n
  113. \r\n     int k;                    //I think you know...  \r\n
  114. \r\n
  115. \r\n       \r\n
  116. \r\n
  117. \r\n     li.LowPart = 1<<21;  \r\n
  118. \r\n
  119. \r\n     li.HighPart = 0;  \r\n
  120. \r\n
  121. \r\n   \r\n
  122. \r\n
  123. \r\n     buffer = (BYTE*)malloc(BUFSIZE);    //5M buffer size  \r\n
  124. \r\n
  125. \r\n     if(buffer == NULL)  \r\n
  126. \r\n
  127. \r\n     {  \r\n
  128. \r\n
  129. \r\n         fprintf(stderr, \"内存分配失败!n\");  \r\n
  130. \r\n
  131. \r\n         return;  \r\n
  132. \r\n
  133. \r\n     }  \r\n
  134. \r\n
  135. \r\n   \r\n
  136. \r\n
  137. \r\n     hFileIn = CreateFile(filespec, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);  \r\n
  138. \r\n
  139. \r\n     if(hFileIn == INVALID_HANDLE_VALUE)  \r\n
  140. \r\n
  141. \r\n     {  \r\n
  142. \r\n
  143. \r\n         free(buffer);  \r\n
  144. \r\n
  145. \r\n         buffer = NULL;  \r\n
  146. \r\n
  147. \r\n         lastErr = GetLastError();  \r\n
  148. \r\n
  149. \r\n         if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, lastErr, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), (LPSTR)&errMsg, 1, NULL))  \r\n
  150. \r\n
  151. \r\n         {  \r\n
  152. \r\n
  153. \r\n             fprintf(stderr, \"CreateFile:%sn%s\", filespec, errMsg);  \r\n
  154. \r\n
  155. \r\n             LocalFree((HLOCAL)errMsg);  \r\n
  156. \r\n
  157. \r\n             errMsg = NULL;  \r\n
  158. \r\n
  159. \r\n         }  \r\n
  160. \r\n
  161. \r\n         return;  \r\n
  162. \r\n
  163. \r\n     }  \r\n
  164. \r\n
  165. \r\n     fileSize = GetFileSize(hFileIn, NULL);  \r\n
  166. \r\n
  167. \r\n     if(fileSize <= 0x00200000)  \r\n
  168. \r\n
  169. \r\n     {  \r\n
  170. \r\n
  171. \r\n         fprintf(stderr, \"文件大小不正确,不能小于2M.(%s)n\", filespec);  \r\n
  172. \r\n
  173. \r\n         free(buffer);  \r\n
  174. \r\n
  175. \r\n         buffer = NULL;  \r\n
  176. \r\n
  177. \r\n         CloseHandle(hFileIn);  \r\n
  178. \r\n
  179. \r\n         hFileIn = NULL;  \r\n
  180. \r\n
  181. \r\n         return;  \r\n
  182. \r\n
  183. \r\n     }  \r\n
  184. \r\n
  185. \r\n   \r\n
  186. \r\n
  187. \r\n     fileSize -= 0x00200000;    //2M offset of REAL Video data  \r\n
  188. \r\n
  189. \r\n   \r\n
  190. \r\n
  191. \r\n     SetFilePointerEx(hFileIn, li, NULL, FILE_BEGIN);  \r\n
  192. \r\n
  193. \r\n     if(!ReadFile(hFileIn, hdr, 4, &dwSizeRead, NULL) || dwSizeRead==0)  \r\n
  194. \r\n
  195. \r\n     {  \r\n
  196. \r\n
  197. \r\n         lastErr = GetLastError();  \r\n
  198. \r\n
  199. \r\n         if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, lastErr, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), (LPSTR)&errMsg, 1, NULL))  \r\n
  200. \r\n
  201. \r\n         {  \r\n
  202. \r\n
  203. \r\n             fprintf(stderr, \"ReadFile:%sn%s\", filespec, errMsg);  \r\n
  204. \r\n
  205. \r\n             LocalFree((HLOCAL)errMsg);  \r\n
  206. \r\n
  207. \r\n             errMsg = NULL;  \r\n
  208. \r\n
  209. \r\n         }  \r\n
  210. \r\n
  211. \r\n         CloseHandle(hFileIn);  \r\n
  212. \r\n
  213. \r\n         hFileIn = NULL;  \r\n
  214. \r\n
  215. \r\n         free(buffer);  \r\n
  216. \r\n
  217. \r\n         buffer = NULL;  \r\n
  218. \r\n
  219. \r\n         return;  \r\n
  220. \r\n
  221. \r\n     }  \r\n
  222. \r\n
  223. \r\n       \r\n
  224. \r\n
  225. \r\n     magicNumber = (338-hdr[1])&0xFF;  \r\n
  226. \r\n
  227. \r\n     if((BYTE)(hdr[1]+magicNumber)==\'R\' && (BYTE)(hdr[2]+magicNumber)==\'M\' && (BYTE)(hdr[3]+magicNumber)==\'F\')  \r\n
  228. \r\n
  229. \r\n     {  \r\n
  230. \r\n
  231. \r\n         fileType = 1;  \r\n
  232. \r\n
  233. \r\n         goto _go;  \r\n
  234. \r\n
  235. \r\n     }  \r\n
  236. \r\n
  237. \r\n       \r\n
  238. \r\n
  239. \r\n     magicNumber = (294-hdr[1])&0xFF;  \r\n
  240. \r\n
  241. \r\n     if((BYTE)(hdr[2]+magicNumber)==178 && (BYTE)(hdr[3]+magicNumber)==117)          \r\n
  242. \r\n
  243. \r\n     {  \r\n
  244. \r\n
  245. \r\n         fileType = 2;  \r\n
  246. \r\n
  247. \r\n         goto _go;  \r\n
  248. \r\n
  249. \r\n     }  \r\n
  250. \r\n
  251. \r\n   \r\n
  252. \r\n
  253. \r\n     magicNumber = (332-hdr[1])&0xFF ;  \r\n
  254. \r\n
  255. \r\n     if((BYTE)(hdr[1]+magicNumber)==76 && (BYTE)(hdr[2]+magicNumber)==86)  \r\n
  256. \r\n
  257. \r\n     {  \r\n
  258. \r\n
  259. \r\n         fileType = 3 ;  \r\n
  260. \r\n
  261. \r\n         goto _go;  \r\n
  262. \r\n
  263. \r\n     }  \r\n
  264. \r\n
  265. \r\n   \r\n
  266. \r\n
  267. \r\n     magicNumber=(329-hdr[1])&0xFF ;  \r\n
  268. \r\n
  269. \r\n     if((BYTE)(hdr[1]+magicNumber)==73 && (BYTE)(hdr[2]+magicNumber)==70 && (BYTE)(hdr[3]+magicNumber)==70)  \r\n
  270. \r\n
  271. \r\n     {  \r\n
  272. \r\n
  273. \r\n         fileType = 4 ;  \r\n
  274. \r\n
  275. \r\n         goto _go;  \r\n
  276. \r\n
  277. \r\n     }  \r\n
  278. \r\n
  279. \r\n     magicNumber=(256-hdr[1])&0xFF ;  \r\n
  280. \r\n
  281. \r\n     if(!(magicNumber+hdr[2]))  \r\n
  282. \r\n
  283. \r\n     {  \r\n
  284. \r\n
  285. \r\n         fileType = 5 ;  \r\n
  286. \r\n
  287. \r\n         goto _go;  \r\n
  288. \r\n
  289. \r\n     }  \r\n
  290. \r\n
  291. \r\n   \r\n
  292. \r\n
  293. \r\n     magicNumber=(256-hdr[1])&0xFF ;  \r\n
  294. \r\n
  295. \r\n     if((BYTE)(hdr[2]+magicNumber)==1 && (BYTE)(hdr[3]+magicNumber)==186)  \r\n
  296. \r\n
  297. \r\n     {  \r\n
  298. \r\n
  299. \r\n         fileType = 6 ;  \r\n
  300. \r\n
  301. \r\n         goto _go;  \r\n
  302. \r\n
  303. \r\n     }  \r\n
  304. \r\n
  305. \r\n   \r\n
  306. \r\n
  307. \r\n     magicNumber=(325-hdr[1])&0xFF ;  \r\n
  308. \r\n
  309. \r\n     if((BYTE)(hdr[1]+magicNumber)==69 && (BYTE)(hdr[2]+magicNumber)==223 && (BYTE)(hdr[3]+magicNumber)==163)  \r\n
  310. \r\n
  311. \r\n     {  \r\n
  312. \r\n
  313. \r\n         fileType = 7 ;  \r\n
  314. \r\n
  315. \r\n         goto _go;  \r\n
  316. \r\n
  317. \r\n     }  \r\n
  318. \r\n
  319. \r\n   \r\n
  320. \r\n
  321. \r\n     fprintf(stderr, \"不能识别的文件格式!(%s)n\", filespec);  \r\n
  322. \r\n
  323. \r\n     free(buffer);  \r\n
  324. \r\n
  325. \r\n     buffer = NULL;  \r\n
  326. \r\n
  327. \r\n     CloseHandle(hFileIn);  \r\n
  328. \r\n
  329. \r\n     hFileIn = NULL;  \r\n
  330. \r\n
  331. \r\n     return;  \r\n
  332. \r\n
  333. \r\n   \r\n
  334. \r\n
  335. \r\n _go:  \r\n
  336. \r\n
  337. \r\n     ch = 0;  \r\n
  338. \r\n
  339. \r\n     pchar = strrchr(filespec,\'\\\');  \r\n
  340. \r\n
  341. \r\n     if(!pchar)  \r\n
  342. \r\n
  343. \r\n         pchar = strrchr(filespec, \'/\');  \r\n
  344. \r\n
  345. \r\n     pchar = pchar==NULL?filespec:pchar+1;  \r\n
  346. \r\n
  347. \r\n     switch(fileType)  \r\n
  348. \r\n
  349. \r\n     {  \r\n
  350. \r\n
  351. \r\n     case 1://rm/rmvb  \r\n
  352. \r\n
  353. \r\n         ch = 46;  \r\n
  354. \r\n
  355. \r\n         sprintf(fileOut, \"%s%s\", pchar, \".rmvb\");  \r\n
  356. \r\n
  357. \r\n         break;  \r\n
  358. \r\n
  359. \r\n     case 2://wmv  \r\n
  360. \r\n
  361. \r\n         ch = 48;  \r\n
  362. \r\n
  363. \r\n         sprintf(fileOut, \"%s%s\", pchar, \".wmv\");  \r\n
  364. \r\n
  365. \r\n         break;  \r\n
  366. \r\n
  367. \r\n     case 3://flv  \r\n
  368. \r\n
  369. \r\n         ch = 70;  \r\n
  370. \r\n
  371. \r\n         sprintf(fileOut, \"%s%s\", pchar, \".flv\");  \r\n
  372. \r\n
  373. \r\n         break;  \r\n
  374. \r\n
  375. \r\n     case 4://avi  \r\n
  376. \r\n
  377. \r\n         ch = 82;  \r\n
  378. \r\n
  379. \r\n         sprintf(fileOut, \"%s%s\", pchar, \".avi\");  \r\n
  380. \r\n
  381. \r\n         break;  \r\n
  382. \r\n
  383. \r\n     case 5://mp4  \r\n
  384. \r\n
  385. \r\n         ch = 0;  \r\n
  386. \r\n
  387. \r\n         sprintf(fileOut, \"%s%s\", pchar, \".mp4\");  \r\n
  388. \r\n
  389. \r\n         break;  \r\n
  390. \r\n
  391. \r\n     case 6://mpeg  \r\n
  392. \r\n
  393. \r\n         ch = 0;  \r\n
  394. \r\n
  395. \r\n         sprintf(fileOut, \"%s%s\", pchar, \".mpeg\");  \r\n
  396. \r\n
  397. \r\n         break;  \r\n
  398. \r\n
  399. \r\n     case 7://mkv  \r\n
  400. \r\n
  401. \r\n         ch = 26;  \r\n
  402. \r\n
  403. \r\n         sprintf(fileOut, \"%s%s\", pchar, \".mkv\");  \r\n
  404. \r\n
  405. \r\n         break;  \r\n
  406. \r\n
  407. \r\n     default:  \r\n
  408. \r\n
  409. \r\n         break;  \r\n
  410. \r\n
  411. \r\n     }  \r\n
  412. \r\n
  413. \r\n     hFileOut = CreateFile(fileOut, GENERIC_WRITE, FILE_SHARE_READ, NULL, /*CREATE_ALWAYS*/CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);  \r\n
  414. \r\n
  415. \r\n     if(hFileOut == INVALID_HANDLE_VALUE)  \r\n
  416. \r\n
  417. \r\n     {  \r\n
  418. \r\n
  419. \r\n         lastErr = GetLastError();  \r\n
  420. \r\n
  421. \r\n         if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, lastErr, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), (LPSTR)&errMsg, 1, NULL))  \r\n
  422. \r\n
  423. \r\n         {  \r\n
  424. \r\n
  425. \r\n             fprintf(stderr, \"CreateFile:%sn%s\", fileOut, errMsg);  \r\n
  426. \r\n
  427. \r\n             LocalFree((HLOCAL)errMsg);  \r\n
  428. \r\n
  429. \r\n             errMsg = NULL;  \r\n
  430. \r\n
  431. \r\n         }  \r\n
  432. \r\n
  433. \r\n         CloseHandle(hFileIn);  \r\n
  434. \r\n
  435. \r\n         hFileIn = NULL;  \r\n
  436. \r\n
  437. \r\n         free(buffer);  \r\n
  438. \r\n
  439. \r\n         buffer = NULL;  \r\n
  440. \r\n
  441. \r\n         return;  \r\n
  442. \r\n
  443. \r\n     }  \r\n
  444. \r\n
  445. \r\n       \r\n
  446. \r\n
  447. \r\n     WriteFile(hFileOut, (LPVOID)&ch, 1, &dwSizeWritten, NULL);  \r\n
  448. \r\n
  449. \r\n       \r\n
  450. \r\n
  451. \r\n     //handle file header  \r\n
  452. \r\n
  453. \r\n     for(k = 1; k < 4; k++)  \r\n
  454. \r\n
  455. \r\n         hdr[k] = (BYTE)((hdr[k]+magicNumber)&0xFF);  \r\n
  456. \r\n
  457. \r\n     WriteFile(hFileOut, &hdr[1], 3, &dwSizeWritten, NULL);  \r\n
  458. \r\n
  459. \r\n   \r\n
  460. \r\n
  461. \r\n     //handle encrypted data. is it simple?  \r\n
  462. \r\n
  463. \r\n     ReadFile(hFileIn, buffer, 1019, &dwSizeRead, NULL);  \r\n
  464. \r\n
  465. \r\n     for(k=0; k<1019; k++)  \r\n
  466. \r\n
  467. \r\n         buffer[k] = (BYTE)(buffer[k]+magicNumber & 0xFF);  \r\n
  468. \r\n
  469. \r\n     WriteFile(hFileOut, buffer, 1019, &dwSizeWritten, NULL);  \r\n
  470. \r\n
  471. \r\n   \r\n
  472. \r\n
  473. \r\n     readSize += 1024;  \r\n
  474. \r\n
  475. \r\n     prtLen = printf(\"%s(%s)\", filespec, strrchr(fileOut, \'.\'));  \r\n
  476. \r\n
  477. \r\n     dotLen = scrWidth-prtLen%scrWidth;  \r\n
  478. \r\n
  479. \r\n     if(dotLen<=10)  \r\n
  480. \r\n
  481. \r\n         dotLen += scrWidth;  \r\n
  482. \r\n
  483. \r\n     dotLen -= 1;  \r\n
  484. \r\n
  485. \r\n     while(dotLen--)  \r\n
  486. \r\n
  487. \r\n         printf(\".\");  \r\n
  488. \r\n
  489. \r\n     //it looks like this: left edge-->|mymov.xv(.flv).............1024M, 99% | <--right edge  \r\n
  490. \r\n
  491. \r\n   \r\n
  492. \r\n
  493. \r\n     //copy rest file, original :-), and show sth. useful. how smart thunder kankan was.  \r\n
  494. \r\n
  495. \r\n     while(ReadFile(hFileIn, buffer, BUFSIZE, &dwSizeRead, NULL) && dwSizeRead != 0)  \r\n
  496. \r\n
  497. \r\n     {  \r\n
  498. \r\n
  499. \r\n         WriteFile(hFileOut, buffer, dwSizeRead, &dwSizeWritten, NULL);  \r\n
  500. \r\n
  501. \r\n         readSize += dwSizeRead;  \r\n
  502. \r\n
  503. \r\n         ResetCursorPos();  \r\n
  504. \r\n
  505. \r\n         printf(\"%4dM,%3d%%\", (int)(readSize/(1<<20)), (int)(readSize/(float)fileSize*100));  \r\n
  506. \r\n
  507. \r\n     }  \r\n
  508. \r\n
  509. \r\n     printf(\"n\");  \r\n
  510. \r\n
  511. \r\n     CloseHandle(hFileIn);  \r\n
  512. \r\n
  513. \r\n     CloseHandle(hFileOut);  \r\n
  514. \r\n
  515. \r\n     hFileIn = NULL;  \r\n
  516. \r\n
  517. \r\n     hFileOut = NULL;  \r\n
  518. \r\n
  519. \r\n     free(buffer);  \r\n
  520. \r\n
  521. \r\n     buffer = NULL;  \r\n
  522. \r\n
  523. \r\n   \r\n
  524. \r\n
  525. \r\n     cntFileProcessed++;  \r\n
  526. \r\n
  527. \r\n     return;  \r\n
  528. \r\n
  529. \r\n }  \r\n
  530. \r\n
  531. \r\n   \r\n
  532. \r\n
  533. \r\n //parse if there to be a wild char  \r\n
  534. \r\n
  535. \r\n void HandleFile(char* filespec)  \r\n
  536. \r\n
  537. \r\n {  \r\n
  538. \r\n
  539. \r\n     WIN32_FIND_DATA fd;  \r\n
  540. \r\n
  541. \r\n     HANDLE hFile = NULL;  \r\n
  542. \r\n
  543. \r\n     char findpath[260];  \r\n
  544. \r\n
  545. \r\n     char tmppath[260];  \r\n
  546. \r\n
  547. \r\n     char* pchar = NULL;  \r\n
  548. \r\n
  549. \r\n   \r\n
  550. \r\n
  551. \r\n     hFile = FindFirstFile(filespec, &fd);  \r\n
  552. \r\n
  553. \r\n     if(hFile == INVALID_HANDLE_VALUE)  \r\n
  554. \r\n
  555. \r\n     {  \r\n
  556. \r\n
  557. \r\n         fprintf(stderr, \"没有文件用于处理!n\");  \r\n
  558. \r\n
  559. \r\n         return;  \r\n
  560. \r\n
  561. \r\n     }  \r\n
  562. \r\n
  563. \r\n   \r\n
  564. \r\n
  565. \r\n     strncpy(findpath, filespec, sizeof(findpath));  \r\n
  566. \r\n
  567. \r\n     //we need to add a full current path to the dest file   \r\n
  568. \r\n
  569. \r\n     //since the fd.cFileName member does not include the path  \r\n
  570. \r\n
  571. \r\n     pchar = strrchr(findpath, \'\\\');  \r\n
  572. \r\n
  573. \r\n     if(!pchar)  \r\n
  574. \r\n
  575. \r\n         pchar = strrchr(findpath, \'/\');    //sometimes, it\'s not back-slash-ed.  \r\n
  576. \r\n
  577. \r\n     if(pchar)  \r\n
  578. \r\n
  579. \r\n         *(pchar+1) = \' \';  \r\n
  580. \r\n
  581. \r\n     do   \r\n
  582. \r\n
  583. \r\n     {  \r\n
  584. \r\n
  585. \r\n         if(!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))    //eliminate directory  \r\n
  586. \r\n
  587. \r\n         {  \r\n
  588. \r\n
  589. \r\n             if(pchar)  \r\n
  590. \r\n
  591. \r\n             {  \r\n
  592. \r\n
  593. \r\n                 sprintf(tmppath, \"%s%s\", findpath, fd.cFileName);    //now it\'s full path  \r\n
  594. \r\n
  595. \r\n                 ExtractFile(tmppath);  \r\n
  596. \r\n
  597. \r\n             }  \r\n
  598. \r\n
  599. \r\n             else  \r\n
  600. \r\n
  601. \r\n             {  \r\n
  602. \r\n
  603. \r\n                 ExtractFile(fd.cFileName);    //in current dir  \r\n
  604. \r\n
  605. \r\n             }  \r\n
  606. \r\n
  607. \r\n         }  \r\n
  608. \r\n
  609. \r\n     } while (FindNextFile(hFile, &fd));    //continue deep search  \r\n
  610. \r\n
  611. \r\n     FindClose(hFile);  \r\n
  612. \r\n
  613. \r\n     hFile = NULL;  \r\n
  614. \r\n
  615. \r\n     return;  \r\n
  616. \r\n
  617. \r\n }  \r\n
  618. \r\n
  619. \r\n   \r\n
  620. \r\n
  621. \r\n void Usage(char* name)  \r\n
  622. \r\n
  623. \r\n {  \r\n
  624. \r\n
  625. \r\n     char* ptr = strrchr(name, \'\\\');    //only the name we need, not the full path  \r\n
  626. \r\n
  627. \r\n     char* pmsg =   \r\n
  628. \r\n
  629. \r\n         \"迅雷看看XV文件提取器 - 版本:1.0n\"  \r\n
  630. \r\n
  631. \r\n         \"作者:女孩不哭 编译时间:\" __DATE__ \" \" __TIME__ \"nn\"  \r\n
  632. \r\n
  633. \r\n         \"使用方法:\"%s /y 文件\", 输出文件在当前工作目录下nn\"  \r\n
  634. \r\n
  635. \r\n         \"敬告:迅雷XV文件包含受版权保护的内容.n\"  \r\n
  636. \r\n
  637. \r\n         \"本程序仅供研究和学习使用, 请自觉将提取的文件立即删除.n\"  \r\n
  638. \r\n
  639. \r\n         \"切勿将本程序及其提取的文件使用于任何其它用途.n\"  \r\n
  640. \r\n
  641. \r\n         \"对于使用本程序造成的任何后果, 由使用者自行承担法律责任!n\"  \r\n
  642. \r\n
  643. \r\n         \"要接受此协议, 请从命令行传入/y作为第1个参数, 文件作为第2个参数.n\";  \r\n
  644. \r\n
  645. \r\n     if(!ptr)  \r\n
  646. \r\n
  647. \r\n         ptr = strrchr(name, \'/\');  \r\n
  648. \r\n
  649. \r\n     if(!ptr)    //the cur dir is just in the exe dir  \r\n
  650. \r\n
  651. \r\n         ptr = name-1;//ptr+1  \r\n
  652. \r\n
  653. \r\n     printf(pmsg, ptr+1);  \r\n
  654. \r\n
  655. \r\n     return;  \r\n
  656. \r\n
  657. \r\n }  \r\n
  658. \r\n
  659. \r\n   \r\n
  660. \r\n
  661. \r\n int main(int argc, char** argv)  \r\n
  662. \r\n
  663. \r\n {  \r\n
  664. \r\n
  665. \r\n     CONSOLE_SCREEN_BUFFER_INFO sbi;  \r\n
  666. \r\n
  667. \r\n     if(argc!=3 || stricmp(argv[1], \"/y\"))    //xve /y file format expected  \r\n
  668. \r\n
  669. \r\n     {  \r\n
  670. \r\n
  671. \r\n         Usage(argv[0]);  \r\n
  672. \r\n
  673. \r\n         return 1;  \r\n
  674. \r\n
  675. \r\n     }  \r\n
  676. \r\n
  677. \r\n     GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &sbi);  \r\n
  678. \r\n
  679. \r\n     scrWidth = sbi.dwSize.X;    //width, in characters  \r\n
  680. \r\n
  681. \r\n   \r\n
  682. \r\n
  683. \r\n     HandleFile(argv[2]);    //enum files if a wild char is detected  \r\n
  684. \r\n
  685. \r\n     printf(\"处理了 %d 个文件!n\", cntFileProcessed);  \r\n
  686. \r\n
  687. \r\n     system(\"pause\");  \r\n
  688. \r\n
  689. \r\n     return 0;  \r\n
  690. \r\n
  691. \r\n
    \r\n
    \r\n
  692. \r\n
\r\n
\r\n
\r\n

\r\n
\r\n

\r\n
\r\n ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2733, 'yuesefu-circle', '约瑟夫环单循环链表的实现【C语言】', '2013-07-18 02:17:08', '2019-03-25 21:29:22', '
\r\n

程序源码

\r\n
\r\n
    \r\n
  1. #include <stdio.h>  
  2. \r\n
  3. typedef struct Node{  
  4. \r\n
  5.    int num;  
  6. \r\n
  7.    int pasword;  
  8. \r\n
  9.    struct Node *next;  
  10. \r\n
  11. } LinkList;  
  12. \r\n
  13.   
  14. \r\n
  15. LinkList *creat(int n) {  
  16. \r\n
  17.    LinkList *p,*q,*head;  
  18. \r\n
  19.    int i=1;  
  20. \r\n
  21.    head=p=(LinkList *)malloc(sizeof(LinkList));  
  22. \r\n
  23.    p->num=i;  
  24. \r\n
  25.    printf(\"请输入第1个人的密码:\");  
  26. \r\n
  27.    scanf(\"%d\",&p->pasword);  
  28. \r\n
  29.    for(i=2;i<=n;i++) {  
  30. \r\n
  31.        q=(LinkList *)malloc(sizeof(LinkList));  
  32. \r\n
  33.        if(q==0) return(0);  
  34. \r\n
  35.        printf(\"请输入第%d个人的密码:\",i);  
  36. \r\n
  37.        scanf(\"%d\",&q->pasword);  
  38. \r\n
  39.        q->num=i;  
  40. \r\n
  41.        p->next=q;  
  42. \r\n
  43.        p=q;  
  44. \r\n
  45.    }  
  46. \r\n
  47.    p->next=head; //使链表尾指向链表头 形成循环链表  
  48. \r\n
  49.    return head;  
  50. \r\n
  51. }  
  52. \r\n
  53.   
  54. \r\n
  55. void fun(LinkList *L)  
  56. \r\n
  57. {  
  58. \r\n
  59.    int m,i;  
  60. \r\n
  61.    LinkList *p=L,*q,*s;  
  62. \r\n
  63.    printf(\"请输入m的初值:\");  
  64. \r\n
  65.    scanf(\"%d\",&m);  
  66. \r\n
  67.    printf(\"出列顺序为:\");  
  68. \r\n
  69.    while(p->next!=p) {  
  70. \r\n
  71.        for(i=1;i<m;i++) {  
  72. \r\n
  73.            q=p;  
  74. \r\n
  75.            p=p->next;  
  76. \r\n
  77.        }  
  78. \r\n
  79.    printf(\"%5d\",p->num);  
  80. \r\n
  81.    m=p->pasword;  
  82. \r\n
  83.    s=p;  
  84. \r\n
  85.    q->next=p->next;  
  86. \r\n
  87.    p=p->next; free(s);  
  88. \r\n
  89.    }  
  90. \r\n
  91.    printf(\"%5d\",p->num);  
  92. \r\n
  93.    printf(\"n\");  
  94. \r\n
  95. }  
  96. \r\n
  97.   
  98. \r\n
  99. main() {  
  100. \r\n
  101.    LinkList *L;  
  102. \r\n
  103.    int n;  
  104. \r\n
  105.    printf(\"请输入实验人数:\");  
  106. \r\n
  107.    scanf(\"%d\",&n);  
  108. \r\n
  109.    L=creat(n);  
  110. \r\n
  111.    fun(L);  
  112. \r\n

  113. \r\n
\r\n
\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2734, '559-2', 'eclipse里面scanf如何会放在所有语句最前面跑?是咋回事', '2013-07-18 01:44:54', '2019-03-25 21:29:22', '

问题:

eclipse里面scanf怎么会放在所有语句最前面跑??是怎么回事
在eclipse里面敲入下面代码:
C/C++ code

int main(int argc, char * argv[]) {

   printf("Hello World!");

   int a;

   scanf("%d",&a);

   printf("Hello World! a is %d", a);


运行,光标自动停在空白开始处,没有第一句Hello World输出,
然后敲入1
回车,则两句Hello World都显示出来了:

1
Hello World!Hello World! a is 1

原因分析:

这是因为 eclipse里面的 printf是先输出到缓冲区的。
所以解决方法,输出后立即刷新输出缓冲
C/C++ code

int main(int argc, char * argv[]) {

   printf("Hello World!");

   fflush(stdout);

   int a;

   scanf("%d",&a);

   printf("Hello World! a is %d", a);

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2735, 'jquery-get-value', 'Jquery获取值的方法', '2013-07-16 00:21:41', '2019-03-25 21:29:22', '

[copy]jquery-get-value[/copy]

\r\n[code lang=\"js\"]\r\n\r\n //获取checkbox绑定的label的值\r\n $(\"#id\").next().text()\r\n //禁用控件\r\n $(\"#id\").attr(\"disabled\", \"disabled\");\r\n //遍历checkbox\r\n $(\'input[type=\"checkbox\"]\').each(\r\n function(){\r\n });\r\n //判断checkbox是否选中\r\n if ($(\"#id\").is(\":checked\")) {\r\n}\r\n //让select的第一项选中\r\n $(\"#id\").get(0).selectedIndex=0\r\n //获取被点击的radio的label的值\r\n $(\"input[type=radio]\").bind(\'click\',function(event){\r\n $(this).next().text()); //被点击的radio的label的值\r\n })\r\n 获取选中的radio值\r\n var rl = $(\'input:radio[name=\"soGroup\"]:checked\').val();\r\n if (rl == null) {\r\n alert(\"什么也没选中!\");\r\n return false;\r\n } else {\r\n alert(rl);\r\n }\r\n\r\n[/code]', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2736, '531', '已知k阶裴波那契序列的定义为...(C语言)', '2013-07-15 00:50:17', '2019-03-25 21:29:22', '

\r\n 题目: \r\n

\r\n

\r\n 已知k阶裴波那契序列的定义为 \r\n

\r\n

\r\n f0=0, f1=0, ..., fk-2=0, fk-1=1; \r\n

\r\n

\r\n fn=fn-1+fn-2+...+fn-k, n=k,k+1,...
\r\n试编写求k阶裴波那契序列的第m项值的函数算法,
\r\nk和m均以值调用的形式在函数参数表中出现。
\r\n

\r\n

\r\n
\r\n

\r\n

\r\n
\r\n

\r\n
\r\n

\r\n 答案
\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n #include <stdio.h>  \r\n
  2. \r\n
  3. \r\n #define OK 1  \r\n
  4. \r\n
  5. \r\n #define ERROR 0  \r\n
  6. \r\n
  7. \r\n   \r\n
  8. \r\n
  9. \r\n int Fibonacci(int k,int m,int *f)  \r\n
  10. \r\n
  11. \r\n /*求k阶斐波那契序列的第m项的值f*/  \r\n
  12. \r\n
  13. \r\n {  \r\n
  14. \r\n
  15. \r\n  int temp[200],i,j,sum;  \r\n
  16. \r\n
  17. \r\n  if(k<2||m<0) return ERROR;  \r\n
  18. \r\n
  19. \r\n  if(m<k-1) f=0;  \r\n
  20. \r\n
  21. \r\n  else if(m==k-1) (*f)=1;  \r\n
  22. \r\n
  23. \r\n  else  \r\n
  24. \r\n
  25. \r\n  {  \r\n
  26. \r\n
  27. \r\n    for(i=0;i<=k-2;i++) temp[i]=0;  \r\n
  28. \r\n
  29. \r\n    temp[k-1]=1;                      //初始化  \r\n
  30. \r\n
  31. \r\n    for(i=k;i<=m;i++)                 //求出序列第k至第m个元素的值  \r\n
  32. \r\n
  33. \r\n    {  \r\n
  34. \r\n
  35. \r\n      sum=0;  \r\n
  36. \r\n
  37. \r\n      for(j=i-k;j<=i-1;j++) sum+=temp[j];  \r\n
  38. \r\n
  39. \r\n      temp[i]=sum;  \r\n
  40. \r\n
  41. \r\n    }  \r\n
  42. \r\n
  43. \r\n    (*f)=temp[m];  \r\n
  44. \r\n
  45. \r\n  }  \r\n
  46. \r\n
  47. \r\n  returnOK;  \r\n
  48. \r\n
  49. \r\n }  \r\n
  50. \r\n
  51. \r\n   \r\n
  52. \r\n
  53. \r\n int main()  \r\n
  54. \r\n
  55. \r\n {  \r\n
  56. \r\n
  57. \r\n int result;  \r\n
  58. \r\n
  59. \r\n Fibonacci(3,2,&result) ;  \r\n
  60. \r\n
  61. \r\n printf(\"%dn\",result);  \r\n
  62. \r\n
  63. \r\n return 0;  \r\n
  64. \r\n
  65. \r\n }  \r\n
  66. \r\n
\r\n
\r\n
\r\n
\r\n

\r\n
\r\n

\r\n

\r\n
\r\n
\r\n

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2737, 'three-numbers-desc', '试写一算法,自大到小依次输出顺序读入的三个整数X,Y和Z的值(C语言)', '2013-07-13 20:56:35', '2019-03-25 21:29:22', '

基本思路:

\r\n
\r\n
\r\n

    定义三个变量a,b,c和辅助变量temp。

\r\n

(1)先将促使a>=b(如果a本身就大于b,则无需操作,否则将a,b交换(借助辅助变量temp)),此步骤完成后必有a>=b

\r\n

(2)将b与c比较,如果b<c,将c的值赋给temp,b的值赋给c,否则b>=c,完毕,;

\r\n

(3)在b<c的前提下,此时,必有b是最小的,将a与temp进行比较,如果a>temp,则有a>c>b,将c的值赋给b即可,否则,有c>a>b,将a赋给b,temp赋给a。

\r\n

 

\r\n

代码展示:

\r\n
\r\n
#include <stdio.h>
#include <stdlib.h>\r\n

void Descending(int *a,int *b,int *c)
{
     int temp=0;
     if(*a<*b){

\r\n

         temp=*a;

\r\n

         *a=*b;

\r\n

         *b=temp;//促使a>=b

\r\n

     }
     if(*b<*c)
     {

\r\n

       temp=*c;

\r\n

       *c=*b;//促使temp>=c

\r\n

       if(*a>=temp) {

\r\n

       *b=temp;

\r\n

       }

\r\n

       else{

\r\n

       *b=*a;

\r\n

       *a=temp;//注意,不能写成a=temp;b=a;

\r\n

       }
     }
}

\r\n

int main()
{
   int a,b,c;
   scanf(\"%d%d%d\",&a,&b,&c);
   Descending(&a,&b,&c);
   printf(\"%d %d %dn\",a,b,c);
   return 0;
}

\r\n
\r\n
\r\n

运行演示:

\r\n

\"\"

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2738, '503', '冒泡排序的算法实现(C语言)', '2013-07-13 20:52:34', '2019-03-25 21:29:22', '
#include <stdio.h>
#define TRUE 1
#define FALSE 0

void BubbleSort(int *a,int n)
{
   int i=0,change=0,j=0;
   for(i=n-1,change=TRUE;i>=1&&change;i--)
   {
       change=FALSE;
       for(j=0;j<i;j++)
       {
           if(a[j]>a[j+1])
           {
               int temp=0;
               temp=a[j];
               a[j]=a[j+1];
               a[j+1]=temp;
               change=TRUE;
           }
       }
   }
}

intmain()
{
   int a[5]={9,6,3,5,4};
   int i=0;
       BubbleSort(a,5);
   
   for(;i<5;i++)
   {    printf("%d ",a[i]);
   }
   printf("n");
   return 0;
}


', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2739, 'matrix-multiplication-algorithm-by-c-language', 'C语言实现矩阵乘法的算法', '2013-07-13 20:51:15', '2019-03-25 21:29:22', '[copy]matrix-multiplication-algorithm-c-language[/copy]\r\n

算法思想

\r\n核心代码是 c[i][j] += a[i][k] * b[k][j]; 充分利用矩阵乘法内标相同的性质,循环遍历每一行,每一列,将a矩阵的每一行乘以b矩阵相应的那一列,结果作为新矩阵的一个(i,j)元。\r\n\r\n本实例以3*3的方阵作为演示。\r\n

代码如下

\r\n
[code lang=\"c\" ]\r\n/*\r\n =====================================================================\r\n Name         :JuZhenChengFa.c\r\n Author       :Tang youwei\r\n Blog         :http://Www.xinValue.Com\r\n Weibo        :http://weibo.com/206464069\r\n QQ           :1035136784(非技术问题勿扰)\r\n Version      :1.0\r\n Copyright    :本程序由@LeaveBugsAway 开发,大家有什么意见建议,欢迎留言。长江大学2010级软工1002唐有炜作品。\r\n Description  :C语言实现矩阵乘法的算法。 充分利用矩阵乘法内标相同的性质,循环遍历每一行,每一列, 将a矩阵的每一行乘以b矩阵相应的那一列,结果作为新矩阵的一个(i,j)元。 另外需掌握C语言的二维数组的灵活性。 本实例以3*3的方阵作为演示。对于一般矩阵,算法思想也是一样的。 在本例中还将打印方法做了封装。\r\n =====================================================================\r\n */\r\n\r\n#include <stdio.h>\r\nvoid JuZhenChengFa(int a[][3], int b[][3], int c[][3]) {\r\n	int i = 0, j = 0, k;\r\n	for (; i < 3; i++) {\r\n		int j = 0;\r\n		for (; j < 3; j++) {\r\n			c[i][j] = 0;\r\n			k = 0;\r\n			for (; k < 3; k++) {\r\n				c[i][j] += a[i][k] * b[k][j];\r\n			}\r\n		}\r\n	}\r\n}\r\n\r\nvoid Print(int a[][3]) {\r\n	int i, j;\r\n	for (i = 0; i < 3; i++) {\r\n		for (j = 0; j < 3; j++) {\r\n			printf(\"%d \", a[i][j]);\r\n		}\r\n		printf(\"n\");\r\n	}\r\n}\r\n\r\nint main() {\r\n	int a[3][3] = { 3, 2, 1, 6, 5, 4, 7, 8, 9 };\r\n	int b[3][3] = { 3, 4, 5, 1, 3, 2, 9, 8, 7 };\r\n	int c[3][3] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };\r\n\r\n	printf(\"a[i][j]=:n\");\r\n	Print(a);\r\n	printf(\"n\");\r\n\r\n	printf(\"b[i][j]=:n\");\r\n	Print(b);\r\n	printf(\"n\");\r\n\r\n	JuZhenChengFa(a, b, c);\r\n\r\n	printf(\"c[i][j]=a[i][j]*b[i][j]=:n\");\r\n	Print(c);\r\n	printf(\"n\");\r\n\r\n}\r\n[/code]
\r\n

运行演示

\r\n\"\"\r\n

在线体验

\r\nhttp://ideone.com/ZjVRAg', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2740, '497', 'y=arcsinx arccosx arctanx arccotx的图像分别是什么样的?', '2013-07-13 19:38:57', '2019-03-25 21:29:22', '
\r\n \"\"
\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2741, 'ssh2', 'Struts2.3.4.1 Spring3.2.3 Hibernate4.1.9_配置步骤', '2013-07-04 16:39:56', '2019-03-25 21:29:22', '

\r\n  \r\n

\r\n

\r\n 一. 创建项目\r\n

\r\n

\r\n \"1\"\r\n

\r\n

\r\n \"2\"\r\n

\r\n

\r\n 二.    搭建struts-2.3.4.11.struts2必须的Jar包(放到WEB-INF/lib目录下):\r\n

\r\n

\r\n \"3\"\r\n

\r\n

\r\n 2.配置struts2.3的过滤器\r\n

\r\n

\r\n web.xml位置\r\n

\r\n

\r\n \"4\"\r\n

\r\n

\r\n  \r\n

\r\n
\r\n

\r\n Web.xml内容\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n <?xml version=\"1.0\" encoding=\"UTF-8\"?> \r\n
  2. \r\n
  3. \r\n <web-app version=\"3.0\" xmlns=\"http://java.sun.com/xml/ns/javaee\" \r\n
  4. \r\n
  5. \r\n     xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" \r\n
  6. \r\n
  7. \r\n     xsi:schemaLocation=\"http://java.sun.com/xml/ns/javaee  \r\n
  8. \r\n
  9. \r\n     http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd\"> \r\n
  10. \r\n
  11. \r\n     <display-name></display-name> \r\n
  12. \r\n
  13. \r\n     <welcome-file-list> \r\n
  14. \r\n
  15. \r\n         <welcome-file>index.jsp</welcome-file> \r\n
  16. \r\n
  17. \r\n     </welcome-file-list> \r\n
  18. \r\n
  19. \r\n  \r\n
  20. \r\n
  21. \r\n     <!-- struts2拦截器 --> \r\n
  22. \r\n
  23. \r\n     <filter> \r\n
  24. \r\n
  25. \r\n         <filter-name>struts2</filter-name> \r\n
  26. \r\n
  27. \r\n     <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> \r\n
  28. \r\n
  29. \r\n     </filter> \r\n
  30. \r\n
  31. \r\n     <filter-mapping> \r\n
  32. \r\n
  33. \r\n         <filter-name>struts2</filter-name> \r\n
  34. \r\n
  35. \r\n         <url-pattern>/*</url-pattern> \r\n
  36. \r\n
  37. \r\n     </filter-mapping> \r\n
  38. \r\n
  39. \r\n  \r\n
  40. \r\n
  41. \r\n </web-app> \r\n
  42. \r\n
\r\n
\r\n
\r\n
\r\n

\r\n 配置struts.xml(struts.xml在src目录下)\r\n

\r\n

\r\n  \r\n

\r\n
\r\n

\r\n Struts.xml内容\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n <?xml version=\"1.0\" encoding=\"UTF-8\" ?> \r\n
  2. \r\n
  3. \r\n <!DOCTYPE struts PUBLIC \r\n
  4. \r\n
  5. \r\n     \"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN\" \r\n
  6. \r\n
  7. \r\n     \"http://struts.apache.org/dtds/struts-2.3.dtd\"> \r\n
  8. \r\n
  9. \r\n  \r\n
  10. \r\n
  11. \r\n <struts> \r\n
  12. \r\n
  13. \r\n     <package name=\"struts2\" extends=\"struts-default\"> \r\n
  14. \r\n
  15. \r\n         <action name=\"TestAction\" class=\"com.xinvalue.action.TestAction\"> \r\n
  16. \r\n
  17. \r\n             <result name=\"success\">/test.jsp</result> \r\n
  18. \r\n
  19. \r\n         </action> \r\n
  20. \r\n
  21. \r\n     </package> \r\n
  22. \r\n
  23. \r\n </struts>     \r\n
  24. \r\n
\r\n
\r\n
\r\n
\r\n

\r\n 4.测试struts2配置\r\n

\r\n

\r\n 新建一个TestAction\r\n

\r\n

\r\n \"5\"\r\n

\r\n
\r\n

\r\n TestAction.java\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n package com.xinvalue.action; \r\n
  2. \r\n
  3. \r\n import com.opensymphony.xwork2.ActionSupport; \r\n
  4. \r\n
  5. \r\n public class TestAction extends ActionSupport { \r\n
  6. \r\n
  7. \r\n     @Override \r\n
  8. \r\n
  9. \r\n     public String execute() throws Exception { \r\n
  10. \r\n
  11. \r\n     return super.execute(); \r\n
  12. \r\n
  13. \r\n     } \r\n
  14. \r\n
  15. \r\n \r\n
  16. \r\n
\r\n
\r\n
\r\n
\r\n

\r\n 新建一个测试页面\r\n

\r\n

\r\n \"6\"\r\n

\r\n

\r\n  \r\n

\r\n

\r\n 成功界面:\r\n

\r\n

\r\n \"7\" 
\r\n
\r\n

\r\n

\r\n 至此,struts2集成完毕!\r\n

\r\n

\r\n 整合Spring 3.2.3和Struts-2.3.4.11.\r\n

\r\n

\r\n 必须的jar包\r\n

\r\n

\r\n 在配置好的strutsjar的基础上,添加额外Struts jar包:\r\n

\r\n

\r\n struts2-spring-plugin-2.3.4.1.jar\r\n

\r\n

\r\n commons-logging-1.1.1.jar\r\n

\r\n

\r\n Spring的jar包:\r\n

\r\n

\r\n \"8\"\r\n

\r\n

\r\n 2.web.xml配置\r\n

\r\n
\r\n

\r\n Web.xml\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n <?xml version=\"1.0\" encoding=\"UTF-8\"?> \r\n
  2. \r\n
  3. \r\n <web-app version=\"3.0\" xmlns=\"http://java.sun.com/xml/ns/javaee\" \r\n
  4. \r\n
  5. \r\n     xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" \r\n
  6. \r\n
  7. \r\n     xsi:schemaLocation=\"http://java.sun.com/xml/ns/javaee  \r\n
  8. \r\n
  9. \r\n     http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd\"> \r\n
  10. \r\n
  11. \r\n     <display-name></display-name> \r\n
  12. \r\n
  13. \r\n     <welcome-file-list> \r\n
  14. \r\n
  15. \r\n         <welcome-file>index.jsp</welcome-file> \r\n
  16. \r\n
  17. \r\n     </welcome-file-list> \r\n
  18. \r\n
  19. \r\n  \r\n
  20. \r\n
  21. \r\n     <!-- struts2拦截器 --> \r\n
  22. \r\n
  23. \r\n     <filter> \r\n
  24. \r\n
  25. \r\n         <filter-name>struts2</filter-name> \r\n
  26. \r\n
  27. \r\n         <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> \r\n
  28. \r\n
  29. \r\n     </filter> \r\n
  30. \r\n
  31. \r\n     <filter-mapping> \r\n
  32. \r\n
  33. \r\n         <filter-name>struts2</filter-name> \r\n
  34. \r\n
  35. \r\n         <url-pattern>/*</url-pattern> \r\n
  36. \r\n
  37. \r\n     </filter-mapping> \r\n
  38. \r\n
  39. \r\n  \r\n
  40. \r\n
  41. \r\n     <!-- 创建spring工厂监听器 --> \r\n
  42. \r\n
  43. \r\n     <listener> \r\n
  44. \r\n
  45. \r\n         <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> \r\n
  46. \r\n
  47. \r\n     </listener> \r\n
  48. \r\n
  49. \r\n  \r\n
  50. \r\n
  51. \r\n     <!-- 告知spring context config location 的存储位置 --> \r\n
  52. \r\n
  53. \r\n     <context-param> \r\n
  54. \r\n
  55. \r\n         <param-name>contextConfigLocation</param-name> \r\n
  56. \r\n
  57. \r\n         <param-value>/WEB-INF/classes/applicationContext.xml</param-value> \r\n
  58. \r\n
  59. \r\n     </context-param> \r\n
  60. \r\n
  61. \r\n  \r\n
  62. \r\n
  63. \r\n </web-app> \r\n
  64. \r\n
\r\n
\r\n
\r\n
\r\n

\r\n 3.spring的applicationContext.xml配置\r\n

\r\n

\r\n  \r\n

\r\n

\r\n \"9\"\r\n

\r\n

\r\n  \r\n

\r\n
\r\n

\r\n applicationContext.xml\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n <?xml version=\"1.0\" encoding=\"UTF-8\"?> \r\n
  2. \r\n
  3. \r\n <beans xmlns=\"http://www.springframework.org/schema/beans\" \r\n
  4. \r\n
  5. \r\n     xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:p=\"http://www.springframework.org/schema/p\" \r\n
  6. \r\n
  7. \r\n     xmlns:tx=\"http://www.springframework.org/schema/tx\" xmlns:context=\"http://www.springframework.org/schema/context\" \r\n
  8. \r\n
  9. \r\n     xsi:schemaLocation=\"http://www.springframework.org/schema/beans  \r\n
  10. \r\n
  11. \r\n             http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  \r\n
  12. \r\n
  13. \r\n             http://www.springframework.org/schema/tx \r\n
  14. \r\n
  15. \r\n             http://www.springframework.org/schema/tx/spring-tx-3.0.xsd \r\n
  16. \r\n
  17. \r\n             http://www.springframework.org/schema/aop \r\n
  18. \r\n
  19. \r\n             http://www.springframework.org/schema/aop/spring-aop-3.0.xsd \r\n
  20. \r\n
  21. \r\n             http://www.springframework.org/schema/context \r\n
  22. \r\n
  23. \r\n             http://www.springframework.org/schema/context/spring-context-3.0.xsd\"> \r\n
  24. \r\n
  25. \r\n  \r\n
  26. \r\n
  27. \r\n </beans> \r\n
  28. \r\n
\r\n
\r\n
\r\n
\r\n

\r\n 整合Hibernate4.1.9 
\r\n1.必需jar包 
\r\n添加Hibernate jar文件 
\r\nHibernate压缩包中的 
\r\nlib/required/ 
\r\n\"10\"\r\n

\r\n

\r\n  \r\n

\r\n

\r\n Spring中的jar文件\r\n

\r\n

\r\n \"11\"\r\n

\r\n

\r\n 数据库连接池支持文件\r\n

\r\n

\r\n \"12\"\r\n

\r\n

\r\n 以及连接mysql的jar 
\r\nmysql-connector-java-5.1.22-bin.jar 
\r\n
\r\n

\r\n

\r\n 2.配置文件applicationContext.xml 
\r\n
\r\n

\r\n
\r\n

\r\n applicationContext.xml\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n <?xml version=\"1.0\" encoding=\"UTF-8\"?> \r\n
  2. \r\n
  3. \r\n <beans xmlns=\"http://www.springframework.org/schema/beans\" \r\n
  4. \r\n
  5. \r\n     xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:p=\"http://www.springframework.org/schema/p\" \r\n
  6. \r\n
  7. \r\n     xmlns:tx=\"http://www.springframework.org/schema/tx\" xmlns:context=\"http://www.springframework.org/schema/context\" \r\n
  8. \r\n
  9. \r\n     xsi:schemaLocation=\"http://www.springframework.org/schema/beans  \r\n
  10. \r\n
  11. \r\n             http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  \r\n
  12. \r\n
  13. \r\n             http://www.springframework.org/schema/tx \r\n
  14. \r\n
  15. \r\n             http://www.springframework.org/schema/tx/spring-tx-3.0.xsd \r\n
  16. \r\n
  17. \r\n             http://www.springframework.org/schema/aop \r\n
  18. \r\n
  19. \r\n             http://www.springframework.org/schema/aop/spring-aop-3.0.xsd \r\n
  20. \r\n
  21. \r\n             http://www.springframework.org/schema/context \r\n
  22. \r\n
  23. \r\n             http://www.springframework.org/schema/context/spring-context-3.0.xsd\"> \r\n
  24. \r\n
  25. \r\n  \r\n
  26. \r\n
  27. \r\n     <!-- 数据库连接 --> \r\n
  28. \r\n
  29. \r\n     <bean id=\"dataSource\" class=\"org.apache.commons.dbcp.BasicDataSource\" \r\n
  30. \r\n
  31. \r\n         destroy-method=\"close\"> \r\n
  32. \r\n
  33. \r\n         <property name=\"driverClassName\"> \r\n
  34. \r\n
  35. \r\n             <value>com.mysql.jdbc.Driver</value> \r\n
  36. \r\n
  37. \r\n         </property> \r\n
  38. \r\n
  39. \r\n  \r\n
  40. \r\n
  41. \r\n         <property name=\"url\"> \r\n
  42. \r\n
  43. \r\n             <value>jdbc:mysql://localhost:3306/ssh2?characterEncoding=utf8</value> \r\n
  44. \r\n
  45. \r\n         </property> \r\n
  46. \r\n
  47. \r\n  \r\n
  48. \r\n
  49. \r\n         <property name=\"username\"> \r\n
  50. \r\n
  51. \r\n             <value>root</value> \r\n
  52. \r\n
  53. \r\n         </property> \r\n
  54. \r\n
  55. \r\n  \r\n
  56. \r\n
  57. \r\n         <property name=\"password\"> \r\n
  58. \r\n
  59. \r\n             <value></value> \r\n
  60. \r\n
  61. \r\n         </property> \r\n
  62. \r\n
  63. \r\n     </bean> \r\n
  64. \r\n
  65. \r\n  \r\n
  66. \r\n
  67. \r\n     <!--Hibernate的Spring配置 --> \r\n
  68. \r\n
  69. \r\n     <bean id=\"sessionFactory\" \r\n
  70. \r\n
  71. \r\n         class=\"org.springframework.orm.hibernate4.LocalSessionFactoryBean\"> \r\n
  72. \r\n
  73. \r\n         <!-- 数据库连接 --> \r\n
  74. \r\n
  75. \r\n         <property name=\"dataSource\"> \r\n
  76. \r\n
  77. \r\n             <ref local=\"dataSource\" /> \r\n
  78. \r\n
  79. \r\n         </property> \r\n
  80. \r\n
  81. \r\n  \r\n
  82. \r\n
  83. \r\n         <!-- hibernate自身属性 --> \r\n
  84. \r\n
  85. \r\n         <property name=\"hibernateProperties\"> \r\n
  86. \r\n
  87. \r\n             <props> \r\n
  88. \r\n
  89. \r\n                 <prop key=\"hibernate.show_sql\">true</prop> \r\n
  90. \r\n
  91. \r\n                 <prop key=\"hibernate.format_sql\">true</prop> \r\n
  92. \r\n
  93. \r\n                 <prop key=\"hibernate.dialect\">org.hibernate.dialect.MySQL5Dialect</prop> \r\n
  94. \r\n
  95. \r\n                 <!-- 解决no session found --> \r\n
  96. \r\n
  97. \r\n                 <prop key=\"hibernate.current_session_context_class\">thread</prop> \r\n
  98. \r\n
  99. \r\n             </props> \r\n
  100. \r\n
  101. \r\n         </property> \r\n
  102. \r\n
  103. \r\n  \r\n
  104. \r\n
  105. \r\n         <!-- 映射文件 --> \r\n
  106. \r\n
  107. \r\n         <property name=\"annotatedClasses\"> \r\n
  108. \r\n
  109. \r\n             <list> \r\n
  110. \r\n
  111. \r\n                 <value>com.xinvalue.bean.User</value> \r\n
  112. \r\n
  113. \r\n             </list> \r\n
  114. \r\n
  115. \r\n         </property> \r\n
  116. \r\n
  117. \r\n     </bean> \r\n
  118. \r\n
  119. \r\n  \r\n
  120. \r\n
  121. \r\n     <!-- 用户Dao --> \r\n
  122. \r\n
  123. \r\n     <bean id=\"userDao\" class=\"com.xinvalue.dao.impl.UserDaoImpl\" \r\n
  124. \r\n
  125. \r\n         scope=\"singleton\"> \r\n
  126. \r\n
  127. \r\n         <property name=\"sessionFactory\"> \r\n
  128. \r\n
  129. \r\n             <ref local=\"sessionFactory\" /> \r\n
  130. \r\n
  131. \r\n         </property> \r\n
  132. \r\n
  133. \r\n     </bean> \r\n
  134. \r\n
  135. \r\n  \r\n
  136. \r\n
  137. \r\n     <!-- 用户Service --> \r\n
  138. \r\n
  139. \r\n     <bean id=\"userService\" class=\"com.xinvalue.service.impl.UserServiceImpl\" \r\n
  140. \r\n
  141. \r\n         scope=\"singleton\"> \r\n
  142. \r\n
  143. \r\n         <property name=\"userDao\"> \r\n
  144. \r\n
  145. \r\n             <ref local=\"userDao\" /> \r\n
  146. \r\n
  147. \r\n         </property> \r\n
  148. \r\n
  149. \r\n     </bean> \r\n
  150. \r\n
  151. \r\n  \r\n
  152. \r\n
  153. \r\n     <!-- 用户Action --> \r\n
  154. \r\n
  155. \r\n     <bean id=\"saveUserAction\" class=\"com.xinvalue.action.SaveUserAction\" \r\n
  156. \r\n
  157. \r\n         scope=\"prototype\"> \r\n
  158. \r\n
  159. \r\n         <property name=\"userService\"> \r\n
  160. \r\n
  161. \r\n             <ref local=\"userService\" /> \r\n
  162. \r\n
  163. \r\n         </property> \r\n
  164. \r\n
  165. \r\n     </bean> \r\n
  166. \r\n
  167. \r\n  \r\n
  168. \r\n
  169. \r\n </beans> \r\n
  170. \r\n
\r\n
\r\n
\r\n
\r\n

\r\n 创建测试数据库\r\n

\r\n
\r\n

\r\n Sql代码\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n CREATE DATABASE `ssh2` ; \r\n
  2. \r\n
  3. \r\n  \r\n
  4. \r\n
  5. \r\n USE `ssh2`; \r\n
  6. \r\n
  7. \r\n  \r\n
  8. \r\n
  9. \r\n DROP TABLE IF EXISTS `users`; \r\n
  10. \r\n
  11. \r\n  \r\n
  12. \r\n
  13. \r\n CREATE TABLE `users` ( \r\n
  14. \r\n
  15. \r\n   `userid` int(11) NOT NULL AUTO_INCREMENT, \r\n
  16. \r\n
  17. \r\n   `username` varchar(20) DEFAULT NULL\r\n
  18. \r\n
  19. \r\n   `userpwd` varchar(20) DEFAULT NULL\r\n
  20. \r\n
  21. \r\n   PRIMARY KEY (`userid`) \r\n
  22. \r\n
  23. \r\n ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC\r\n
  24. \r\n
  25. \r\n  \r\n
  26. \r\n
  27. \r\n insert  into `users`(`userid`,`username`,`userpwd`) values (1,\'terwer\',\'123456\'); \r\n
  28. \r\n
\r\n
\r\n
\r\n
\r\n

\r\n 创建bean\r\n

\r\n

\r\n \"13\"\r\n

\r\n

\r\n  \r\n

\r\n
\r\n

\r\n User.java\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n package com.xinvalue.bean; \r\n
  2. \r\n
  3. \r\n  \r\n
  4. \r\n
  5. \r\n import javax.persistence.Column; \r\n
  6. \r\n
  7. \r\n import javax.persistence.Entity; \r\n
  8. \r\n
  9. \r\n import javax.persistence.Id; \r\n
  10. \r\n
  11. \r\n import javax.persistence.Table; \r\n
  12. \r\n
  13. \r\n  \r\n
  14. \r\n
  15. \r\n @Entity \r\n
  16. \r\n
  17. \r\n @Table(name = \"users\"\r\n
  18. \r\n
  19. \r\n public class User { \r\n
  20. \r\n
  21. \r\n     @Id \r\n
  22. \r\n
  23. \r\n     private int userId; \r\n
  24. \r\n
  25. \r\n     @Column(name = \"username\"\r\n
  26. \r\n
  27. \r\n     private String username; \r\n
  28. \r\n
  29. \r\n     @Column(name = \"userpwd\"\r\n
  30. \r\n
  31. \r\n     private String userpwd; \r\n
  32. \r\n
  33. \r\n  \r\n
  34. \r\n
  35. \r\n     public int getUserId() { \r\n
  36. \r\n
  37. \r\n     return userId; \r\n
  38. \r\n
  39. \r\n     } \r\n
  40. \r\n
  41. \r\n  \r\n
  42. \r\n
  43. \r\n     public void setUserId(int userId) { \r\n
  44. \r\n
  45. \r\n     this.userId = userId; \r\n
  46. \r\n
  47. \r\n     } \r\n
  48. \r\n
  49. \r\n  \r\n
  50. \r\n
  51. \r\n     public String getUsername() { \r\n
  52. \r\n
  53. \r\n     return username; \r\n
  54. \r\n
  55. \r\n     } \r\n
  56. \r\n
  57. \r\n  \r\n
  58. \r\n
  59. \r\n     public void setUsername(String username) { \r\n
  60. \r\n
  61. \r\n     this.username = username; \r\n
  62. \r\n
  63. \r\n     } \r\n
  64. \r\n
  65. \r\n  \r\n
  66. \r\n
  67. \r\n     public String getUserpwd() { \r\n
  68. \r\n
  69. \r\n     return userpwd; \r\n
  70. \r\n
  71. \r\n     } \r\n
  72. \r\n
  73. \r\n  \r\n
  74. \r\n
  75. \r\n     public void setUserpwd(String userpwd) { \r\n
  76. \r\n
  77. \r\n     this.userpwd = userpwd; \r\n
  78. \r\n
  79. \r\n     } \r\n
  80. \r\n
  81. \r\n \r\n
  82. \r\n
\r\n
\r\n
\r\n
\r\n

\r\n 创建dao\r\n

\r\n

\r\n  \r\n

\r\n

\r\n \"14\"\r\n

\r\n

\r\n  \r\n

\r\n
\r\n

\r\n UserDao.java\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n package com.xinvalue.dao; \r\n
  2. \r\n
  3. \r\n  \r\n
  4. \r\n
  5. \r\n import java.util.List; \r\n
  6. \r\n
  7. \r\n  \r\n
  8. \r\n
  9. \r\n import com.xinvalue.bean.User; \r\n
  10. \r\n
  11. \r\n  \r\n
  12. \r\n
  13. \r\n public interface UserDao { \r\n
  14. \r\n
  15. \r\n     public List<User> queryAllUsers(); \r\n
  16. \r\n
  17. \r\n  \r\n
  18. \r\n
  19. \r\n     boolean saveUser(User user); \r\n
  20. \r\n
  21. \r\n \r\n
  22. \r\n
\r\n
\r\n
\r\n
\r\n
\r\n

\r\n UserDaoImpl.java\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n package com.xinvalue.dao.impl; \r\n
  2. \r\n
  3. \r\n  \r\n
  4. \r\n
  5. \r\n import java.util.List; \r\n
  6. \r\n
  7. \r\n  \r\n
  8. \r\n
  9. \r\n import org.hibernate.Session; \r\n
  10. \r\n
  11. \r\n import org.hibernate.SessionFactory; \r\n
  12. \r\n
  13. \r\n import org.hibernate.Transaction; \r\n
  14. \r\n
  15. \r\n import com.xinvalue.bean.User; \r\n
  16. \r\n
  17. \r\n import com.xinvalue.dao.UserDao; \r\n
  18. \r\n
  19. \r\n  \r\n
  20. \r\n
  21. \r\n public class UserDaoImpl implements UserDao { \r\n
  22. \r\n
  23. \r\n     private SessionFactory sessionFactory; \r\n
  24. \r\n
  25. \r\n  \r\n
  26. \r\n
  27. \r\n     public SessionFactory getSessionFactory() { \r\n
  28. \r\n
  29. \r\n     return sessionFactory; \r\n
  30. \r\n
  31. \r\n     } \r\n
  32. \r\n
  33. \r\n  \r\n
  34. \r\n
  35. \r\n     public void setSessionFactory(SessionFactory sessionFactory) { \r\n
  36. \r\n
  37. \r\n     this.sessionFactory = sessionFactory; \r\n
  38. \r\n
  39. \r\n     } \r\n
  40. \r\n
  41. \r\n  \r\n
  42. \r\n
  43. \r\n     @Override \r\n
  44. \r\n
  45. \r\n     public List<User> queryAllUsers() { \r\n
  46. \r\n
  47. \r\n     // TODO Auto-generated method stub \r\n
  48. \r\n
  49. \r\n     return null\r\n
  50. \r\n
  51. \r\n     } \r\n
  52. \r\n
  53. \r\n  \r\n
  54. \r\n
  55. \r\n     @Override \r\n
  56. \r\n
  57. \r\n     public boolean saveUser(User user) { \r\n
  58. \r\n
  59. \r\n     Session session = sessionFactory.getCurrentSession(); \r\n
  60. \r\n
  61. \r\n     Transaction tx = session.beginTransaction(); \r\n
  62. \r\n
  63. \r\n     try \r\n
  64. \r\n
  65. \r\n         session.save(user); \r\n
  66. \r\n
  67. \r\n         tx.commit(); \r\n
  68. \r\n
  69. \r\n         return true\r\n
  70. \r\n
  71. \r\n     } catch (Exception e) { \r\n
  72. \r\n
  73. \r\n         if (e != null) { \r\n
  74. \r\n
  75. \r\n         tx.rollback(); \r\n
  76. \r\n
  77. \r\n         } \r\n
  78. \r\n
  79. \r\n     } \r\n
  80. \r\n
  81. \r\n     return false\r\n
  82. \r\n
  83. \r\n     } \r\n
  84. \r\n
  85. \r\n \r\n
  86. \r\n
\r\n
\r\n
\r\n
\r\n

\r\n 创建Service\r\n

\r\n

\r\n  \r\n

\r\n

\r\n \"15\"\r\n

\r\n

\r\n  \r\n

\r\n
\r\n

\r\n UserService.java\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n package com.xinvalue.service; \r\n
  2. \r\n
  3. \r\n  \r\n
  4. \r\n
  5. \r\n import java.util.List; \r\n
  6. \r\n
  7. \r\n  \r\n
  8. \r\n
  9. \r\n import com.xinvalue.bean.User; \r\n
  10. \r\n
  11. \r\n  \r\n
  12. \r\n
  13. \r\n public interface UserService { \r\n
  14. \r\n
  15. \r\n     public List<User> queryAllUsers(); \r\n
  16. \r\n
  17. \r\n  \r\n
  18. \r\n
  19. \r\n     boolean saveUser(User user); \r\n
  20. \r\n
  21. \r\n \r\n
  22. \r\n
\r\n
\r\n
\r\n
\r\n

\r\n  \r\n

\r\n
\r\n

\r\n UserServiceImpl.java\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n package com.xinvalue.service.impl; \r\n
  2. \r\n
  3. \r\n  \r\n
  4. \r\n
  5. \r\n import java.util.List; \r\n
  6. \r\n
  7. \r\n  \r\n
  8. \r\n
  9. \r\n import com.xinvalue.bean.User; \r\n
  10. \r\n
  11. \r\n import com.xinvalue.dao.UserDao; \r\n
  12. \r\n
  13. \r\n import com.xinvalue.service.UserService; \r\n
  14. \r\n
  15. \r\n  \r\n
  16. \r\n
  17. \r\n public class UserServiceImpl implements UserService { \r\n
  18. \r\n
  19. \r\n      private UserDao userDao; \r\n
  20. \r\n
  21. \r\n  \r\n
  22. \r\n
  23. \r\n      public UserDao getUserDao() { \r\n
  24. \r\n
  25. \r\n         return userDao; \r\n
  26. \r\n
  27. \r\n     } \r\n
  28. \r\n
  29. \r\n  \r\n
  30. \r\n
  31. \r\n     public void setUserDao(UserDao userDao) { \r\n
  32. \r\n
  33. \r\n         this.userDao = userDao; \r\n
  34. \r\n
  35. \r\n     } \r\n
  36. \r\n
  37. \r\n  \r\n
  38. \r\n
  39. \r\n     @Override \r\n
  40. \r\n
  41. \r\n     public List<User> queryAllUsers() { \r\n
  42. \r\n
  43. \r\n     return userDao.queryAllUsers(); \r\n
  44. \r\n
  45. \r\n     } \r\n
  46. \r\n
  47. \r\n  \r\n
  48. \r\n
  49. \r\n     @Override \r\n
  50. \r\n
  51. \r\n     public boolean saveUser(User user) { \r\n
  52. \r\n
  53. \r\n     return userDao.saveUser(user); \r\n
  54. \r\n
  55. \r\n     } \r\n
  56. \r\n
  57. \r\n  \r\n
  58. \r\n
  59. \r\n \r\n
  60. \r\n
\r\n
\r\n
\r\n
\r\n

\r\n 创建Action\r\n

\r\n

\r\n \"16\"\r\n

\r\n

\r\n  \r\n

\r\n
\r\n

\r\n SaveUserAction.java\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n package com.xinvalue.action; \r\n
  2. \r\n
  3. \r\n  \r\n
  4. \r\n
  5. \r\n import com.opensymphony.xwork2.ActionSupport; \r\n
  6. \r\n
  7. \r\n import com.xinvalue.bean.User; \r\n
  8. \r\n
  9. \r\n import com.xinvalue.service.UserService; \r\n
  10. \r\n
  11. \r\n  \r\n
  12. \r\n
  13. \r\n public class SaveUserAction extends ActionSupport { \r\n
  14. \r\n
  15. \r\n  \r\n
  16. \r\n
  17. \r\n     private UserService userService; \r\n
  18. \r\n
  19. \r\n     private String username; \r\n
  20. \r\n
  21. \r\n     private String userpwd; \r\n
  22. \r\n
  23. \r\n  \r\n
  24. \r\n
  25. \r\n     public UserService getUserService() { \r\n
  26. \r\n
  27. \r\n     return userService; \r\n
  28. \r\n
  29. \r\n     } \r\n
  30. \r\n
  31. \r\n  \r\n
  32. \r\n
  33. \r\n     public void setUserService(UserService userService) { \r\n
  34. \r\n
  35. \r\n     this.userService = userService; \r\n
  36. \r\n
  37. \r\n     } \r\n
  38. \r\n
  39. \r\n  \r\n
  40. \r\n
  41. \r\n     public String getUsername() { \r\n
  42. \r\n
  43. \r\n     return username; \r\n
  44. \r\n
  45. \r\n     } \r\n
  46. \r\n
  47. \r\n  \r\n
  48. \r\n
  49. \r\n     public void setUsername(String username) { \r\n
  50. \r\n
  51. \r\n     this.username = username; \r\n
  52. \r\n
  53. \r\n     } \r\n
  54. \r\n
  55. \r\n  \r\n
  56. \r\n
  57. \r\n     public String getUserpwd() { \r\n
  58. \r\n
  59. \r\n     return userpwd; \r\n
  60. \r\n
  61. \r\n     } \r\n
  62. \r\n
  63. \r\n  \r\n
  64. \r\n
  65. \r\n     public void setUserpwd(String userpwd) { \r\n
  66. \r\n
  67. \r\n     this.userpwd = userpwd; \r\n
  68. \r\n
  69. \r\n     } \r\n
  70. \r\n
  71. \r\n  \r\n
  72. \r\n
  73. \r\n     @Override \r\n
  74. \r\n
  75. \r\n     public String execute() throws Exception { \r\n
  76. \r\n
  77. \r\n     User user = new User(); \r\n
  78. \r\n
  79. \r\n     user.setUsername(this.getUsername()); \r\n
  80. \r\n
  81. \r\n     user.setUserpwd(this.getUserpwd()); \r\n
  82. \r\n
  83. \r\n     boolean status=userService.saveUser(user); \r\n
  84. \r\n
  85. \r\n     System.out.println(status); \r\n
  86. \r\n
  87. \r\n     return SUCCESS; \r\n
  88. \r\n
  89. \r\n     } \r\n
  90. \r\n
  91. \r\n \r\n
  92. \r\n
\r\n
\r\n
\r\n
\r\n

\r\n 创建测试页面:\r\n

\r\n

\r\n \"20\"\r\n

\r\n
\r\n

\r\n addUser.jsp\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n <body> \r\n
  2. \r\n
  3. \r\n     <s:form action=\"SaveUserAction.action\"> \r\n
  4. \r\n
  5. \r\n         <s:textfield name=\"username\" label=\"用户名\"/> \r\n
  6. \r\n
  7. \r\n         <s:password name=\"userpwd\" label=\"密码\"/> \r\n
  8. \r\n
  9. \r\n         <s:submit label=\"注册\"/> \r\n
  10. \r\n
  11. \r\n     </s:form> \r\n
  12. \r\n
  13. \r\n </body> \r\n
  14. \r\n
\r\n
\r\n
\r\n
\r\n

\r\n 成功界面:\r\n

\r\n

\r\n \"17\"\r\n

\r\n

\r\n  \r\n

\r\n

\r\n \"18\"\r\n

\r\n

\r\n  \r\n

\r\n

\r\n \"19\"\r\n

\r\n

\r\n  \r\n

\r\n

\r\n 至此,全部整合完毕!\r\n

\r\n

\r\n 附:项目所有jar包下载:ss2-libs\r\n

\r\n

\r\n 如有大家有什么问题,可以给我留言,我会抽时间一一解答。\r\n

\r\n

\r\n 笔者微博:@LeaveBugsAway欢迎叨扰。\r\n

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2742, '482-2', 'tomcat问题: "The APR based Apache Tomcat Native library which allows optimal perf', '2013-07-03 22:28:30', '2019-03-25 21:29:22', '

问题信息详细:

信息:2013-7-3 22:32:06 org.apache.catalina.core.AprLifecycleListener init
信息: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: C:SoftMyEclipseCommonbinarycom.sun.java.jdk.win32.x86_1.6.0.013bin;C:SoftTomcat 7.0bin

问题出现的原因:

tomcat推荐使用apache的apr(Apache portable Run-time libraries,Apache可移植运行库).


解决方法:

下载地址:http://archive.apache.org/dist/tomcat/tomcat-connectors/native


通过上述链接下载tcnative-1.dll文件, 如图, 你可以自己选择最新的版本,然后将下载下来的文件放到C:WINDOWSsystem32中即可, 重启tomcat就可以。


解决后:

2013-7-3 22:33:56 org.apache.catalina.core.AprLifecycleListener init
信息: Loaded APR based Apache Tomcat Native library 1.1.24 using APR version 1.4.6.

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2743, 'sql-2005-alert', '安装SQL 2005 出现警告 32位ASP.NET已经注册,需要注册64位……解决方案', '2013-06-28 20:14:16', '2019-03-25 21:29:22', '
\r\n

可以运行以下两条命令:

\r\n

1.将64位.net注册到iis上。

\r\n

cscript C:inetpubadminscriptsadsutil.vbs SETW3SVC/AppPools/Enable32bitAppOnWin64 0

\r\n

\r\n

C:WINDOWSMicrosoft.NETFramework64v2.0.50727aspnet_regiis.exe -i

\r\n

\r\n

2.注册32位.net:

\r\n

不需要卸载32位,注册命令就是上面的命令。系统默认安装的是64位系统,但是由于客户程序大部分都是在32位.net下开发,因此默认将iis的.net注册成了32位的版本,方便客户使用。如运行以上命令安装成功后,需要运行

\r\n

cscript C:inetpubadminscriptsadsutil.vbs SETW3SVC/AppPools/Enable32bitAppOnWin64 1

\r\n

\r\n

C:WINDOWSMicrosoft.NETFrameworkv2.0.50727aspnet_regiis.exe -i

\r\n

重新将32位.net注册到iis中,避免32位程序无法在64位.net下运行。默认环境下可以安装成功。

\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2744, 'time-is-up-but-can-not-fetch-connection', '超时时间已到。超时时间已到,但是尚未从池中获取连接。出现这种情况可能是因为所有池连接均在使用', '2013-06-10 11:02:16', '2019-03-25 21:29:22', '
\r\n

本文转载自:http://www.jiaonan.tv/html/blog/1/25668.htm,略有改动。超时时间已到,但是尚未从池中获取连接。
  出现这种情况可能是因为所有池连接均在使用,并且达到了最大池大小。
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. Exception Details: System.InvalidOperationException: 超时时间已到。超时时间已到,但是尚未从池中获取连接。
出现这种情况可能是因为所有池连接均在使用,并且达到了最大池大小。  
 
说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。 异常详细信息: System.InvalidOperationException: 超时时间已到。超时时间已到,但是尚未从池中获取连接。出现这种情况可能是因为所有池连接均在使用,并且达到了最大池大小。 这是个老问题了!
你就查两点:
一、看所有open的连接是否都close了。
 
二、如果访问量很大,加上Max Pool Size=512这一句,当然这是要以损失系统性能为代价的! 这样以后一定可以解决你的问题!  
解决方案一 我想原因可能是并发操作。DataReader是独占连接的,就是说你的程序可能设计上有问题。比如说最大连接设100,假设有100个人同时使用 DataReader正在读取数据库内容,那么当第101人读取的时候,连接池中的连接已经没有了,就会出现上面的错误。DataReader是独占连接 的,每个DataReader都要占用一个连接。当然这个情况是偶尔出现的,所以会很长时间出现一次,因为只有同时有超过连接池最大连接数量的并发操作才会发生。而且你加大并发数量只能暂时缓解问题,如果你加大到200个并发连接,如果有201 人同时操作怎么办?你说了你使用Connection对象的Close()方法,这是不行的,因为Close()方法仅仅是关闭连接,但这个连接没有释放,还是被这个对象占用,要释放必须使用Connection的Dispose()方法显式释放连接才可以,否则这个对象占用的连接只能等到垃圾收集的情 况下才能被释放。这种情况肯定会出现“超时时间已到”的错误。 解决方法: 1 修改几个关键页面或访问比较频繁的数据库访问操作,使用DataAdapter和DataSet来获取数据库数据,不要使用DataReader。  
2 在访问数据库的页面上使用数据缓存,如果页面的数据不是经常更新(几分钟更新一次)的话,使用Cache对象可以不用访问数据库而使用缓存中的内容,那么可以大大减少连接数量。  
3 修改代码,把使用Connection对象的地方都在Close()后面加上Dispose()调用。  
4 建议对数据库操作进行大的修改,建立自己的数据库操作代理类,继承
System.IDisposable接口,强迫释放资源,这样就不会出现连接数量不够的问题了。  
解决方案二 解决方法(*):
WEB.config 里面:在数据库连接加  

\r\n
<add name=\"con\" connectionString=\"Max Pool Size = 51200;Data Source=Max Pool Size = 512;
server=local;uid=;pwd=;database=2004;Max Pool Size = 512;\" />
\r\n

一劳永逸。 解决方案三  
估计是连接(Connection)对象没有Close。倒是不必Dispose,而DataReader用完后应该关闭,但不关闭也没问题,只是不关闭的话此连接对象就一直不能用,只要你最终关闭了连接对象就不会出问题。 连接对象在Open后的操作都放在try块中,后面跟一个finally块:conn.Close();

\r\n

 

\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2745, '466-2', 'ORACLE需要开启的服务', '2013-06-06 14:07:47', '2019-03-26 00:27:17', '启动Oracle 11g服务
\r\n
\r\n
\r\n
\r\n
    \r\n
  1. \r\n @echo off  \r\n
  2. \r\n
  3. \r\n @ ECHO 启动 Oracle 11g 服务  \r\n
  4. \r\n
  5. \r\n net start \"OracleDBConsoleorcl\"  \r\n
  6. \r\n
  7. \r\n net start \"OracleOraDb11g_home1TNSListener\"  \r\n
  8. \r\n
  9. \r\n net start \"OracleServiceORCL\"  \r\n
  10. \r\n
  11. \r\n @ ECHO 启动完毕 按任意键继续  \r\n
  12. \r\n
  13. \r\n pause     \r\n
  14. \r\n
  15. \r\n exi  \r\n
  16. \r\n
\r\n
\r\n
\r\n
\r\n
\r\n

\r\n
\r\n

\r\n
\r\n

\r\n 停止Oracle 11g服务
\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n @echo off  \r\n
  2. \r\n
  3. \r\n @ ECHO 停止 Oracle 11g 服务  \r\n
  4. \r\n
  5. \r\n net stop \"OracleDBConsoleorcl\"  \r\n
  6. \r\n
  7. \r\n net stop \"OracleOraDb11g_home1TNSListener\"  \r\n
  8. \r\n
  9. \r\n net stop \"OracleServiceORCL\"  \r\n
  10. \r\n
  11. \r\n @ ECHO 停止完毕 按任意键继续  \r\n
  12. \r\n
  13. \r\n pause  \r\n
  14. \r\n
  15. \r\n exit  \r\n
  16. \r\n
\r\n
\r\n
\r\n
\r\n

\r\n
\r\n

\r\n
\r\n
\r\n
\r\n
\r\n
\r\n

\r\n
\r\n

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2746, 'could-not-load-file-or-assembly-xxx-or-one-of-its-dependencies-trying-to-load-a-malformed-program', '未能加载文件或程序集“XXX”或它的某一个依赖项。试图加载格式不正确的程序', '2013-06-05 13:03:04', '2019-03-25 21:29:22', '

错误提示

\r\n未能加载文件或程序集“Common”或它的某一个依赖项。试图加载格式不正确的程序。\r\n\r\n说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。\r\n\r\n异常详细信息: System.BadImageFormatException: 未能加载文件或程序集“Common”或它的某一个依赖项。试图加载格式不正确的程序。\r\n\"QQ截图20141221151419\"\r\n

错误环境

\r\n第一次:Windows 2008 Server R2 64位;\r\n\r\n第二次:Windows 7 64位;\r\n

原因分析

\r\n操作系统是64位的,但发布的程序引用了一些32位的ddl,所以出现了兼容性的问题。\r\n

解决方案

\r\n1、将应用程序生成为Any CPU,如果系统是64位的Win7,就应该将新项目的生成目标平台改为x86。\r\n\r\n\"QQ截图20141221152010\"\r\n\r\n2、IIS——应用程序池——高级设置——启用32位应用程序 :true。\r\n\r\n\"QQ截图20141221151346\"', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2747, '458-2', 'Could not open ServletContext resource applicationContext.xml解决方法', '2013-06-01 20:07:12', '2019-03-25 21:29:22', '

问题:

严重: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener\r\norg.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from ServletContext resource [/WEB-INF/applicationContext.xml]; nested exception is java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/applicationContext.xml]\r\n    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:349)\r\n    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:310)\r\n    at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:143)\r\n    at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:178)\r\n    at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:149)\r\n    at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:124)\r\n    at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:92)\r\n    at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:123)\r\n    at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:422)\r\n    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:352)\r\n    at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:255)\r\n    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:199)\r\n    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:45)\r\n    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3827)\r\n    at org.apache.catalina.core.StandardContext.start(StandardContext.java:4334)\r\n    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:791)\r\n    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:771)\r\n    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:525)\r\n    at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:920)\r\n    at org.apache.catalina.startup.HostConfig.deployDirectories(HostConfig.java:883)\r\n    at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:492)\r\n    at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1138)\r\n    at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:311)\r\n    at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)\r\n    at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1053)\r\n    at org.apache.catalina.core.StandardHost.start(StandardHost.java:719)\r\n    at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)\r\n    at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)\r\n    at org.apache.catalina.core.StandardService.start(StandardService.java:516)\r\n    at org.apache.catalina.core.StandardServer.start(StandardServer.java:710)\r\n    at org.apache.catalina.startup.Catalina.start(Catalina.java:566)\r\n    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\r\n    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)\r\n    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)\r\n    at java.lang.reflect.Method.invoke(Method.java:597)\r\n    at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288)\r\n    at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)\r\nCaused by: java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/applicationContext.xml]\r\n    at org.springframework.web.context.support.ServletContextResource.getInputStream(ServletContextResource.java:117)\r\n    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:336)\r\n    ... 36 more\r\n2013-6-1 20:09:33 org.apache.catalina.core.StandardContext start


解决方案:

在web.xml中加入这些配置

<context-param>\r\n    <param-name>contextConfigLocation </param-name>\r\n    <param-value>/WEB-INF/classes/applicationContext.xml </param-value>\r\n</context-param>

原因分析:
问题主要由于加载spring的默认配置文件位置一般是在/WEB-INF/下找applicationContext.xml文件。而Myeclipse文件自动生成的applicationContext文件是放在/WEB-INF/classes/applicationContext.xml。所以在默认加载中是找不到applicationContext.xml文件的,必须加入上面配置。

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2748, '454-2', '电脑安装office2003的时候提示系统管理员设置了组策略,禁止进行些安装', '2013-06-01 17:15:32', '2019-03-25 21:29:22', '

解决办法:

在“开始-运行”中输入regedit.exe,点“确定”打开注册表;

定位到HKEY_CLASSES_ROOTInstallerProducts4080110900063D11C8EF10054038389C

注册表项目。将其删除就搞定了

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2749, 'java-connect-oracle-10g', 'Java连接oracle10g数据库', '2013-06-01 15:47:57', '2019-03-25 21:29:22', '

一、创建数据库:\r\n

\r\n

1.创建表空间

\r\n

\r\n\r\n
\r\n

Sql代码

\r\n
\r\n
\r\n
    \r\n
  1. CREATE SMALLFILE TABLESPACE \"TYW\" DATAFILE
  2. \r\n
  3. \'C:ORACLEPRODUCT10.1.0ORADATAORCLtyw\' SIZE 100M LOGGING EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO
  4. \r\n
  5. BEGIN DBMS_SERVER_ALERT.SET_THRESHOLD(9000,NULL,NULL,NULL,NULL,1,1,
  6. \r\n
  7. NULL,5,\'TYW\');
  8. \r\n
  9. END;
  10. \r\n
\r\n
\r\n
\r\n
\r\n \r\n

\r\n

2.创建用户:

\r\n

\r\n\r\n
\r\n

Sql代码

\r\n
\r\n
\r\n
    \r\n
  1. CREATE USER \"TERWER\" PROFILE \"DEFAULT\" IDENTIFIED BY \"*******\" ACCOUNT UNLOCK
  2. \r\n
  3. GRANT \"CONNECT\" TO \"TERWER\"
  4. \r\n
\r\n
\r\n
\r\n
\r\n \r\n

\r\n

3.授权用户

\r\n

\r\n\r\n
\r\n

Sql代码

\r\n
\r\n
\r\n
    \r\n
  1. alter user terwer default tablespace TYW;
  2. \r\n
  3. grant unlimited tablespace to terwer;
  4. \r\n
\r\n
\r\n
\r\n
\r\n \r\n

4.创建表

\r\n

\r\n\r\n
\r\n

Sql代码

\r\n
\r\n
\r\n
    \r\n
  1. CREATE TABLE \"TERWER\".\"TB_ADMIN\" ( \"USERNAME\" VARCHAR2(50), \"USERPWD\" VARCHAR2(50)) TABLESPACE \"TYW\"
  2. \r\n
\r\n
\r\n
\r\n
\r\n \r\n\r\n5.插入数据\r\n\r\n \r\n
\r\n

Sql代码

\r\n
\r\n
\r\n
    \r\n
  1. INSERT INTO \"TERWER\".\"TB_ADMIN\"(\"USERNAME\",\"USERPWD\" ) VALUES (\'admin\',\'123456\')
  2. \r\n
\r\n
\r\n
\r\n
\r\n \r\n\r\n二、Java连接oracle10g数据库\r\n\r\n1.首先建立一个java项目,加入ojdbc6.jar(点此下载)驱动到项目路径\r\n\r\n2.建立一个类ConnOracle,加入以下代码\r\n
\r\n

ConnOracle.java

\r\n
\r\n
\r\n
    \r\n
  1. package com.xinvalue;  
  2. \r\n
  3.      
  4. \r\n
  5. import java.sql.Statement;  
  6. \r\n
  7. import java.sql.Connection;  
  8. \r\n
  9. import java.sql.DriverManager;  
  10. \r\n
  11. import java.sql.ResultSet;  
  12. \r\n
  13.      
  14. \r\n
  15. public class ConnOracle  
  16. \r\n
  17. {  
  18. \r\n
  19.     public static void main(String[] args) {  
  20. \r\n
  21.         try  
  22. \r\n
  23.         {  
  24. \r\n
  25.             String driver = \"oracle.jdbc.OracleDriver\";  
  26. \r\n
  27.             String url = \"jdbc:oracle:thin:@localhost:1521:ORCL\";  
  28. \r\n
  29.             String username = \"terwer\";  
  30. \r\n
  31.             String userpwd = \"cbgtyw2020\";  
  32. \r\n
  33.             Class.forName(driver);// 加载驱动器  
  34. \r\n
  35.             Connection conn = DriverManager.getConnection(url, username,  
  36. \r\n
  37.                     userpwd);// 建立连接  
  38. \r\n
  39.             Statement stmt = conn.createStatement();  
  40. \r\n
  41.             String sql = \"SELECT * FROM TB_ADMIN\"// 执行SQL语句  
  42. \r\n
  43.             ResultSet rs = stmt.executeQuery(sql);  
  44. \r\n
  45.             while (rs.next())  
  46. \r\n
  47.             {  
  48. \r\n
  49.                 System.out.println(rs.getString(\"USERNAME\") + \" \");  
  50. \r\n
  51.                 System.out.println(rs.getString(\"USERPWD\") + \"n\");  
  52. \r\n
  53.             }  
  54. \r\n
  55.         } catch (Exception e)  
  56. \r\n
  57.         {  
  58. \r\n
  59.             e.printStackTrace();  
  60. \r\n
  61.         }  
  62. \r\n
  63.     }  
  64. \r\n
  65.      
  66. \r\n
  67. \r\n
\r\n
\r\n
\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2750, '445-2', 'oeacle10g应用程序要求的数据库权限超出了您当前具有的权限', '2013-06-01 15:28:21', '2019-03-25 21:29:22', '

打开sqlplus,输入

grant SELECT_CATALOG_ROLE to user

其中user就是你要授权的用户名。


', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2751, '437-2', 'C#删除文件及文件夹', '2013-05-28 17:00:30', '2019-03-25 21:29:22', '

\r\n \r\n

\r\n 本文转载自:http://www.cnblogs.com/wggWeb/archive/2012/02/23/2364521.html ,略有改动的。\r\n
\r\n\r\n

\r\n

\r\n 现提供2种方法:
\r\n
\r\n1这是最简单的方法\r\n

\r\n

\r\n DirectoryInfo di = new DirectoryInfo(string Path);\r\n

\r\n

\r\n di.Delete(true);
\r\n注:path是你要删除的非空目录;
\r\n    true:你要删除里面所有的文件,包括文件夹和子文件夹
\r\n2\r\n

\r\n

\r\n         /// <summary>\r\n

\r\n

\r\n        /// 删除非空文件夹\r\n

\r\n

\r\n        /// </summary>\r\n

\r\n

\r\n        /// <paramname=\"path\">要删除的文件夹目录</param>\r\n

\r\n

\r\n        private void DeleteDirectory(string path)\r\n

\r\n

\r\n        {\r\n

\r\n

\r\n            DirectoryInfo dir = new DirectoryInfo(path);\r\n

\r\n

\r\n            if(dir.Exists)\r\n

\r\n

\r\n            {\r\n

\r\n

\r\n                DirectoryInfo[] childs = dir.GetDirectories();\r\n

\r\n

\r\n                foreach(DirectoryInfo child in childs)\r\n

\r\n

\r\n                {\r\n

\r\n

\r\n                    child.Delete(true);\r\n

\r\n

\r\n                }\r\n

\r\n

\r\n                dir.Delete(true);\r\n

\r\n

\r\n            }\r\n

\r\n

\r\n        }\r\n

\r\n

\r\n
\r\n

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2752, 'vs2010-stay', 'VS2010 SP1安装过程停留在VS10Sp1-KB983509解决方案', '2013-05-28 12:10:48', '2019-03-25 21:29:22', '

 

\r\n
\r\n

本文转载自:http://jiangtao0222.blog.163.com/blog/static/980919512011922956237/,略有改动。

\r\n

1.拷贝VS2010安装包中的vs_setup.msi文件到C:WindowsInstaller文件夹下,并改名为43289.msi。

\r\n

2.重新安装SP1。

\r\n

ok,that\'s all。

\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2753, '424-2', 'C#文章的new图标自动消失', '2013-05-27 21:40:28', '2019-03-26 00:27:51', '

不费话了,直接来数据绑定的代码:

<%#  DataBinder.Eval(Container.DataItem,"IsLatest").

ToString()=="true"

&&

((Int32)TimeSpan.Parse((DateTime.Now - DateTime.Parse

(DataBinder.Eval(Container.DataItem, "SubmitTime").

ToString())).ToString()).TotalDays)<= 7

?"<img class='picNew'src='/UpLoads/images/new.gif'

alt='new'/>":""

%>



', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2755, 'install-win8-sql-server-2005-solution', 'win8安装SQL Server 2005问题解决方法', '2013-05-13 21:21:13', '2019-03-25 21:29:22', '

[copy]install-win8-sql-server-2005-solution[/copy]

\r\n

1、正常安装任一版本的SQL Server 2005(最好安装企业版)。

\r\n

2、安装到SqlServer服务的时候提示启动服务失败(提示重试的时候),这里就是关键啦,下载本文的两个附件,里面是SP4(2005.90.5000.0)版本的sqlservr.exe和sqlos.dll。

\r\n

sqlservr64.rar

\r\n

sqlservr32.rar

\r\n

3、进入SQL Server 2005的安装路径,进入MSSQL文件夹下面的Binn文件夹,在该文件夹里面搜索“sqlservr.exe”文件,并把它复制一份到桌面或其它地方作为备份,然后把上面第2步下载的文件解压出 sqlservr.exe和sqlos.dll两个文件,复制到Binn文件夹里面覆盖原文件(即点击替换)。

\r\n

例如“C:Program FilesMicrosoft SQL ServerMSSQL.2MSSQLBinn”。

\r\n

4、点击“重试”,安装继续,安装程序安装成功。

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2756, '410-2', 'win8在在桌面添加计算机(我的电脑)显示的方法', '2013-05-13 18:15:01', '2019-03-25 21:29:22', '

\r\n 本文转载自http://diybbs.zol.com.cn/1/34036_992.html, 略有改动。\r\n

\r\n

\r\n Windows有个传统,桌面默认是没有计算机(我的电脑)的,要自己手动加上,很多人的方法应该都是下图那样,开始菜单右键计算机添加,可惜Win8没有开始菜单了,所以这个方法不能用了,这几天看不到有不少人问怎么添加计算机到桌面,下面分享一个方法,其实在Win7和XP里,也是这么设置的。
\r\n
\r\n1、右键单击桌面空白处,在弹出的菜单选择个性化
\r\n

\r\n2、选择更改桌面图标
\r\n

\r\n3、选择你要在桌面上显示的项目,勾中即可,比如你要在桌面显示计算机(我的电脑),选中,点确定,就可以了。
\r\n
\r\n\r\n

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2757, '405-2', 'struts2中关于There is no Action mapped for namespace...的总结', '2013-05-08 16:40:30', '2019-03-25 21:29:22', '

\r\n 今天在调试一个基础的Struts2框架小程序。总是提示\"There is no Action mapped for namespace / and action name\"的错误。上网查询后发现这是一个初学者经常碰到的问题,导致错误的原因总结如下:\r\n

\r\n

\r\n 1、struts.xml文件名错误。一定要注意拼写问题;\r\n

\r\n

\r\n 2、struts.xml文件放置路径错误。一定要将此文件放置在src目录下。编译成功后,要确认是否编译到classes目录中。
\r\n

\r\n

\r\n 3、struts.xml文件内容错误。下面给出一个正确的struts.xml文件以供参考。\r\n

\r\n

\r\n \r\n

\r\n

\r\n Struts.xml\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n <?xml version=\"1.0\" encoding=\"UTF-8\"?>  \r\n
  2. \r\n
  3. \r\n <!DOCTYPE struts PUBLIC  \r\n
  4. \r\n
  5. \r\n         \"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN\"  \r\n
  6. \r\n
  7. \r\n         \"http://struts.apache.org/dtds/struts-2.3.dtd\">  \r\n
  8. \r\n
  9. \r\n      \r\n
  10. \r\n
  11. \r\n <struts>  \r\n
  12. \r\n
  13. \r\n     <package name=\"default\" namespace=\"/\" extends=\"struts-default\">  \r\n
  14. \r\n
  15. \r\n         <action name=\"article\" class=\"com.xinvalue.action.ArticleAction\">  \r\n
  16. \r\n
  17. \r\n             <result name=\"success\">/ok.jsp</result>  \r\n
  18. \r\n
  19. \r\n         </action>  \r\n
  20. \r\n
  21. \r\n     </package>  \r\n
  22. \r\n
  23. \r\n </struts> 
    \r\n
    \r\n
  24. \r\n
\r\n
\r\n
\r\n
\r\n\r\n

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2758, '402-2', 'Wordpress数据库结构详解', '2013-05-08 13:45:22', '2019-03-25 21:29:22', '

WordPress仅仅用了10 个表:wp_comments, wp_links, wp_options, wp_postmeta,wp_posts, wp_term_relationships, wp_term_taxonomy, wp_terms,wp_usermeta, wp_users

按照功能大致分为五类
用户信息:wp_users和wp_usermeta
链接信息: wp_links
文章及评论信息:wp_posts、wp_postmeta、wp_comments
对分类,链接分类,标签管理:wp_term,wp_term_relationships,wp_term_taxonomy
全局设置信息: wp_options

wp_posts
博客发表”文章”存放的地方就是这个wp_posts表了。这个表里存放的除了普通的文章之外,还有附件和页面(page)的一些信息。post_type字段是用来区分文章类型的。如果post_type是’post’,那么就是文章,如果是’page’,那么就是页面,如果是’attachment’,那么就是附件了.

wp_postmeta
这个表很简单,只有 meta_id, post_id, meta_key, meta_value 这四个字段。post_id 是相关“文章” 的id。meta_value 是longtext类型的,这里仅是用来存储值。在撰写文章的时候,在编辑框下面有一个Custom Fields 的选项,我们可以在这里添加post的meta信息。

wp_comments
比较重要的两个字段是 comment_post_ID 和comment_approved,前一个用来指示这条评论隶属于哪一篇文章,后一个用来记录审核状况。还有一个比较有意思的是这个commnet_agent 字段,可以利用这个字段来统计一下用户浏览器类型。

wp_users
用户帐号表。存储用户名、密码还有一些用户的基本信息。

wp_usermeta
类似上面的 wp_postmeta,存储一些其他的用户信息。

wp_options
用来记录Wordpress的一些设置和选项。里面有一个blog_id字段,这个应该是用在MU版里面来标示不同的 Blog的。autoload这个字段用来控制是否选项总是被WordPress或者插件导入并缓存来使用,或者是否只是在要求的情况下才被导入。

wp_links
用来存储 Blogroll 里面的链接。

wp_terms
它保存(term)的基本信息。name 就是 term 的名字,slug 是用于使得 URL 友好化。term_group是用于把相似的 terms 集合在一起。term_id 是term的唯一ID。

wp_term_taxonomy
分类信息,是对wp_terms中的信息的关系信息补充,有所属类型(category,link_category,tag),详细描述所拥有文章(链接)数量。

wp_term_relationships
把posts和links这些对象和term_taxonomy表中的term_taxonomy_id联系起来的关系表,object_id是与不同的对象关联,例如wp_posts中的ID(wp_links中的link_id)等,term_taxonomy_id就是关联wp_term_taxonomy中的term_taxonomy_id。

WordPress使用MySQL数据库。作为一个开发者,我们有必要掌握WordPress数据库的基本构造,并在自己的插件或主题中使用他们。

截至WordPress3.0,WordPress一共有以下11个表。这里加上了默认的表前缀 wp_

wp_commentmeta:存储评论的元数据
wp_comments:存储评论
wp_links:存储友情链接(Blogroll)
wp_options:存储WordPress系统选项和插件、主题配置
wp_postmeta:存储文章(包括页面、上传文件、修订)的元数据
wp_posts:存储文章(包括页面、上传文件、修订)
wp_terms:存储每个目录、标签
wp_term_relationships:存储每个文章、链接和对应分类的关系
wp_term_taxonomy:存储每个目录、标签所对应的分类
wp_usermeta:存储用户的元数据
wp_users:存储用户

在WordPress的数据库结构中,存储系统选项和插件配置的wp_options表是比较独立的结构,在后文中会提到,它采用了key-value模式存储,这样做的好处是易于拓展,各个插件都可以轻松地在这里存储自己的配置。

post,comment,user则是三个基本表加上拓展表的组合。以wp_users为例,wp_users已经存储了每个用户会用到的基本信息,比如login_name、display_name、password、email等常用信息,但如果我们还要存储一些不常用的数据,最好的做法不是去在表后加上一列,去破坏默认的表结构,而是将数据存在wp_usermeta中。wp_usermeta这个拓展表和wp_options表有类似的结构,我们可以在这里存储每个用户的QQ号码、手机号码、登录WordPress后台的主题选项等等。

比较难以理解的是term,即wp_terms、wp_term_relationships、wp_term_taxonomy。在WordPress的系统里,我们常见的分类有文章的分类、链接的分类,实际上还有TAG,它也是一种特殊的分类方式,我们甚至还可以创建自己的分类方法。WordPress将所有的分类及分类方法、对应结构都记录在这三个表中。wp_terms记录了每个分类的名字以及基本信息,如本站分为“WordPress开发”、“WPCEO插件”等,这里的分类指广义上的分类,所以每个TAG也是一个“分类”。wp_term_taxonomy记录了每个分类所归属的分类方法,如“WordPress开发”、“WPCEO插件”是文章分类(category),放置友情链接的“我的朋友”、“我的同事”分类属于友情链接分类(link_category)。wp_term_relationships记录了每个文章(或链接)所对应的分类方法。

庆幸的是,关于term的使用,WordPress中相关函数的使用方法还是比较清晰明了,我们就没必要纠结于它的构造了。

上面,我们已经介绍了WordPress数据库中各个表的作用,本文将继续介绍每个表中每个列的作用。WordPress官方文档已经有比较详细的表格,本文仅对常用数据进行介绍。

wp_commentmeta
meta_id:自增唯一ID
comment_id:对应评论ID
meta_key:键名
meta_value:键值


wp_comments
comment_ID:自增唯一ID
comment_post_ID:对应文章ID
comment_author:评论者
comment_author_email:评论者邮箱
comment_author_url:评论者网址
comment_author_IP:评论者IP
comment_date:评论时间
comment_date_gmt:评论时间(GMT+0时间)
comment_content:评论正文
comment_karma:未知
comment_approved:评论是否被批准
comment_agent:评论者的USER AGENT
comment_type:评论类型(pingback/普通)
comment_parent:父评论ID
user_id:评论者用户ID(不一定存在)

wp_links
link_id:自增唯一ID
link_url:链接URL
link_name:链接标题
link_image:链接图片
link_target:链接打开方式
link_description:链接描述
link_visible:是否可见(Y/N)
link_owner:添加者用户ID
link_rating:评分等级
link_updated:未知
link_rel:XFN关系
link_notes:XFN注释
link_rss:链接RSS地址

wp_optio\r\nns
option_id:自增唯一ID
blog_id:博客ID,用于多用户博客,默认0
option_name:键名
option_value:键值
autoload:在WordPress载入时自动载入(yes/no)

wp_postmeta
meta_id:自增唯一ID
post_id:对应文章ID
meta_key:键名
meta_value:键值

wp_posts
ID:自增唯一ID
post_author:对应作者ID
post_date:发布时间
post_date_gmt:发布时间(GMT+0时间)
post_content:正文
post_title:标题
post_excerpt:摘录
post_status:文章状态(publish/auto-draft/inherit等)
comment_status:评论状态(open/closed)
ping_status:PING状态(open/closed)
post_password:文章密码
post_name:文章缩略名
to_ping:未知
pinged:已经PING过的链接
post_modified:修改时间
post_modified_gmt:修改时间(GMT+0时间)
post_content_filtered:未知
post_parent:父文章,主要用于PAGE
guid:未知
menu_order:排序ID
post_type:文章类型(post/page等)
post_mime_type:MIME类型
comment_count:评论总数

wp_terms
term_id:分类ID
name:分类名
slug:缩略名
term_group:未知
wp_term_relationships
object_id:对应文章ID/链接ID
term_taxonomy_id:对应分类方法ID
term_order:排序
wp_term_taxonomy
term_taxonomy_id:分类方法ID
term_id:taxonomy:分类方法(category/post_tag)
description:未知
parent:所属父分类方法ID
count:文章数统计

wp_usermeta
umeta_id:自增唯一ID
user_id:对应用户ID
meta_key:键名
meta_value:键值

wp_users
ID:自增唯一ID
user_login:登录名
user_pass:密码
user_nicename:昵称
user_email:Email
user_url:网址
user_registered:注册时间
user_activation_key:激活码
user_status:用户状态
display_name:显示名称

WordPress数据库中的表、字段、类型及说明

wordpress中各个表的字段,折腾WordPress必备良品~


wp_categories: 用于保存分类相关信息的表。包括了5个字段,分别是:

  • cat_ID – 每个分类唯一的ID号,为一个bigint(20)值,且带有附加属性auto_increment。

  • cat_name – 某个分类的名称,为一个varchar(55)值。

  • category_nicename –指定给分类的一个便于记住的名字,也就是所谓的slug,这是一个varchar(200)值。

  • category_description – 某个分类的详细说明,longtext型值。

  • category_parent –分类的上级分类,为一个int(4)值,对应是的当前表中的cat_ID,即wp_categories.cat_ID。无上级分类时,这个值为0。



wp_comments: 用于保存评论信息的表。包括了15个字段,分别为:

  • comment_ID – 每个评论的唯一ID号,是一个bigint(20)值。带有附加属性auto_increment。

  • comment_post_ID – 每个评论对应的文章的ID号,int(11)值,等同于wp_posts.ID。

  • comment_author – 每个评论的评论者名称,tinytext值。

  • comment_author_email – 每个评论的评论者电邮地址,varchar(100)值。

  • comment_author_url – 每个评论的评论者网址,varchar(200)值。

  • comment_author_IP – 每个评论的评论者的IP地址,varchar(100)值。

  • comment_date – 每个评论发表的时间,datetime值(是加上时区偏移量后的值)。

  • comment_date_gmt – 每个评论发表的时间,datetime值(是标准的格林尼治时间)。

  • comment_content – 每个评论的具体内容,text值。

  • comment_karma – 不详,int(11)值,默认为0。

  • comment_approved –每个评论的当前状态,为一个枚举值enum(’0′,’1′,’spam’),0为等待审核,1为允许发布,spam为垃圾评论。默认值为1。

  • comment_agent –每个评论的评论者的客户端信息,varchar(255)值,主要包括其浏览器和操作系统的类型、版本等资料。

  • comment_type – 不详,varchar(20)值。

  • comment_parent –某一评论的上级评论,int(11)值,对应wp_comment.ID,默认为0,即无上级评论。

  • user_id –某一评论对应的用户ID,只有当用户注册后才会生成,int(11)值,对应wp_users.ID。未注册的用户,即外部评论者,这个ID的值为0。



wp_linkcategories: 用于保存在WP后台中添加的链接的相关信息的表。包括13个字段:

  • cat_id – 每个链接分类的唯一ID,bigint(20)值,为一个自增量auto_increment。

  • cat_name – 每个链接分类的名字,tinytext值。

  • auto_toggle-这个字段所包含的是一个比较特别的属性。如果为Y,则当该分类中加入了新链接时,其它的链接会变为不可见。它是一个枚举型的值enum(’Y’,’N’),默认为N。

  • show_images – 该字段也是枚举值enum(’Y’,’N’),默认为Y。用户指定是否允许在该链接分类显示图片链接。

  • show_description –该字段指定相应的链接分类下的链接,是否再专门[换行]显示它们的说明,这是一个枚举型值enum(’Y’,’N’),默认为N,即不显示说明(但会通过title属性中显示说明)。

  • show_rating –显示该分类下链接的等级。它也是一个枚举值enum(’Y’,’N’),默认为Y。此时,你可以用链接等级的方式来对该链接分类下的链接进行排序。

  • show_updated – 指定该链接分类有更新是,是否进行显示,枚举值enum(’Y’,’N’),默认为Y。

  • sort_order –指定该链接分类中链接的排序依据,varchar(64)值。一般用链接的名字(name,即wp_links.link_name)或ID(id,即wp_links.link_id)。

  • sort_desc – 指定链接分类的排序方式,枚举值enum(’Y’,’N’),默认为N,即用降序。

  • text_before_link –该链接分类下每个链接的前置html文本,varchar(128)值,默认是’列表开始标签’。

  • text_after_link –该链接分类下每个链接的中,链接与说明文字(wp_links.link_description)之间的html文本,varchar(128)值,默认是’换行标签’。

  • text_after_all –该链接分类下每个链接的后置html文本,varchar(128)值,默认是’列表结束标签’。

  • list_limit –用于规定某一链接分类中显示的(可设定的?)链接的个数,int(11)值,默认为-1,即对链接分类下链接的个数无限制。

wp_links :用于保存用户输入到Wordpress中的链接(通过LinkManager)的表。共14个字段:

  • link_id – 每个链接的唯一ID号,bigint(20)值,附加属性为auto_increment。

  • link_url – 每个链接的URL地址,varchar(255)值,形式为http://开头的地址。

  • link_name – 单个链接的名字,varchar(255)值。

  • link_image – 链接可以被定义为使用图片链接,这个字段用于保存该图片的地址,为varchar(255)值。

  • link_target –链接打开的方式,有三种,_blank为以新窗口打开,_top为就在本窗口中打开并在最上一级,none为不选择,会在本窗口中打开。这个字段是varchar(25)值。

  • link_category –某个链接对应的链接分类,为int(11)值。相当于wp_linkcategories.cat_id。

  • link_description –链接的说明文字。用户可以选择显示在链接下方还是显示在title属性中。varchar(255)值。

  • link_visible – 该链接是否可以,枚举enum(’Y’,’N’)值,默认为Y,即可见。

  • link_owner – 某个链接的创建人,为一int(11)值,默认是1。(应该对应的就是wp_users.ID)

  • link_rating – 链接的等级,int(11)值。默认为0。

  • link_updated – 链接被定义、修改的时间,datetime值。

  • link_rel – 链接与定义者的关系,由XFN Creator设置,varchar(255)值。

  • link_notes – 链接的详细说明,mediumtext值。

  • link_rss – 该链接的RSS地址,varchar(255)值。



wp_options: 用于保存Wordpress相关设置、参数的表,共11个字段。最重要是的option_value字段,里面包括了大量的重要信息。

  • option_id – 选项的ID,bigint(20)值,附加auto_increment属性。

  • blog_id –不详。或许用在单在用户的WP版本上并不重要吧,或许是针对不同用户的Blog来设置的一个值。int(11)值,默认为0,即当前blog。

  • option_name – 选项名称,varchar(64)值。

  • option_can_override –该选项是否可被重写、更新,枚举enum(’Y’,’N’)值,默认为Y,即可被重写、更新。

  • option_type – 选项的类型,作用不详,int(11)值,默认为1。

  • option_value –选项的值,longtext值,这个字段的内容比较重要。Wordpress初始化时就会设定好约70个默认的值,这里暂不介绍。

  • option_width – 选项的宽(?),作用不详。int(11)值,默认为20。

  • option_height – 选项的高(?),作用不详。int(11)值,默认为8。

  • option_description – 针对某个选项的说明,tinytext值。

  • option_admin_level – 设定某个选项可被操纵的用户等级(详情见我的相关文章),int(11)值,默认为1。

  • autoload – 选项是否每次都被自动加载,枚举enum(’yes’,’no’)值,默认为yes。



wp_post2cat: 用于保存文章(posts)与分类(categories)之间的关系的表,只有三个字段:

  • rel_id – 关联ID,bigint(20)值,是个有auto_increment属性的自增量。

  • post_id – 文章的ID,bigint(20)值,相当于wp_posts.ID。

  • category_id – 分类的ID,也是bigint(20)值,相当于wp_categories.ID。

文章与分类的关系的形成是这样的:rel_id是一个不断增加的自增量,它用于识别每不同的post。post_id可以重复(当它对应多个分类时),因为它可被rel_id识别,所以不会出现混乱。每个post_id可对应多个category_id时,一个rel_id+post_id组合,可以识别某一个分类,因此每个文章的分类可以是不同的。通过这张表,可以非常快速、高效地找出某篇文章(post)对应了哪些分类(category),反之亦然。



wp_postmeta: 用于保存文章的元信息(meta)的表,四个字段:

  • meta_id – 元信息ID,bigint(20)值,附加属性为auto_increment。

  • post_id – 文章ID,bigint(20)值,相当于wp_posts.ID。

  • meta_key – 元信息的关键字,varchar(255)值。

  • meta_value – 元信息的值,text值。

这些内容主要是在文章及页面编辑页(Write Post, Write Page)的”Add a new custom field tothispost(page):”下进行设定的。meta_key就对应名为”key”的下拉列表中的项,而值由用户自己填上(某些时候,wp也会自动加入,如文章中有的音频媒体)。



wp_posts: 用于保存你所有的文章(posts)的相关信息的表,非常的重要。一般来讲,它存储的数据是最多的。一共包括了21个字段。
ID – 每篇文章的唯一ID,bigint(20)值,附加属性auto_increment。

  • post_author – 每篇文章的作者的编号,int(4)值,应该对应的是wp_users.ID。

  • post_date – 每篇文章发表的时间,datetime值。它是GMT时间加上时区偏移量的结果。

  • post_date_gmt – 每篇文章发表时的GMT(格林威治)时间,datetime值。

  • post_content – 每篇文章的具体内容,longtext值。你在后台文章编辑页面中写入的所有内容都放在这里。

  • post_title – 文章的标题,text值。

  • post_category – 文章所属分类,int(4)值。

  • post_excerpt – 文章摘要,text值。

  • post_status –文章当前的状态,枚举enum(’publish’,’draft’,’private’,’static’,’object’)值,publish为已发表,draft为草稿,private为私人内容(不会被公开),static(不详),object(不详)。默认为publish。

  • comment_status –评论设置的状态,也是枚举enum(’open’,’closed’,’registered_only’)值,open为允许评论,closed为不允许评论,registered_only为只有注册用户方可评论。默认为open,即人人都可以评论。

  • ping_status –ping状态,枚举enum(’open’,’closed’)值,open指打开pingback功能,closed为关闭。默认值是open。

  • post_password –文章密码,varchar(20)值。文章编辑才可为文章设定一个密码,凭这个密码才能对文章进行重新强加或修改。

  • post_name –文章名,varchar(200)值。这通常是用在生成permalink时,标识某篇文章的一段文本或数字,也即postslug。

  • to_ping – 强制该文章去ping某个URI。text值。

  • pinged – 该文章被pingback的历史记录,text值,为一个个的URI。

  • post_modified – 文章最后修改的时间,datetime值,它是GMT时间加上时区偏移量的结果。

  • post_modified_gmt – 文章最后修改的GMT时间,datetime值。

  • post_content_filtered – 不详,text值。

  • post_parent –文章的上级文章的ID,int(11)值,对应的是wp_posts.ID。默认为0,即没有上级文章。

  • guid – 这是每篇文章的一个地址,varchar(255)值。默认是这样的形式:http://your.blog.site/?p=1,如果你形成permalink功能,则通常会是:你的Wordpress站点地址+文章名。

  • menu_order – 不详,int(11)值,默认为0。

  • post_type – 文章类型,具体不详,varchar(100)值。默认为0。

  • post_mime_type – 不详。varchar(100)值。

  • comment_count – 评论计数,具体用途不详,bigint(20)值。



wp_usermeta: 用于保存用户元信息(meta)的表,共4个字段:

  • umeta_id – 元信息ID,bigint(20)值,附加属性auto_increment。

  • user_id – 元信息对应的用户ID,bigint(20)值,相当于wp_users.ID。

  • meta_key – 元信息关键字,varchar(255)值。

  • meta_value – 元信息的详细值,longtext值。



wp_users:用于保存Wordpress使用者的相关信息的表。WP官方对2.0.2版本中该表的情况的说明有些矛盾(称有22个字段,但详细的列表中只有11个),所以这里只能列出11个字段进行说明:

  • ID– 用户唯一ID,bigint(20)值,带附加属性auto_increment。

  • user_login – 用户的注册名称,varchar(60)值。

  • user_pass – 用户密码,varchar(64)值,这是经过加密的结果。好象用的是不可逆的MD5算法。

  • user_nicename – 用户昵称,varchar(50)值。

  • user_email – 用户电邮地址,varchar(100)值。

  • user_url – 用户网址,varchar(100)值。

  • user_registered – 用户注册时间,datetime值。

  • user_level – 用于等级,int(2)值,可以是0-10之间的数字,不同等级有不同的对WP的操作权限。

  • user_activation_key – 用户激活码,不详。varchar(60)值。

  • user_status – 用户状态,int(11)值,默认为0。

  • display_name – 来前台显示出来的用户名字,varchar(250)值。


', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2759, 'mysql-delete-table-with-the-same-prefix', '快速批量删除mysql数据库相同前缀的数据库表', '2013-12-08 23:45:39', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

\r\n

代码如下:

\r\n
[code lang=\"php\"]mysql_connect(\'数据库服务器地址\',\'数据库用户名\',\'数据库密码\');\r\nmysql_select_db(\'数据库名称\');\r\n$rs=mysql_query(\'show tables\');\r\nwhile($arr=mysql_fetch_array($rs)){\r\n    $TF=strpos($arr[0],\'cms_\');\r\n    if($TF===0){\r\n        $FT=mysql_query(\"drop table $arr[0]\");\r\n        if($FT){\r\n            echo \"$arr[0] 删除成功!\";\r\n            }\r\n        }\r\n    }\r\n[/code]
\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2760, '388-2', '使用vs2010和masm32搭建win32汇编语言编程编译环境', '2013-05-05 19:54:54', '2019-03-25 21:29:22', '

\r\n 本文转载自:http://hi.baidu.com/myregion/item/e46c3a56ab3c93c09f266765,略有改动。\r\n

\r\n

\r\n 具体操作步骤:\r\n

\r\n

\r\n 1.安装masm32,安装的时候一般都会要求你安装到某个盘符根目录下,满足它。\r\n

\r\n

\r\n 下载地址:masm32-install.exe\r\n

\r\n

\r\n 2.安装vs2010,没有什么具体要求。\r\n

\r\n

\r\n 3.配置vs2010为C++编译环境。\r\n

\r\n

\r\n 4.运行vs2010,生成空工程。\r\n

\r\n

\r\n 5.选择生成自定义项:在你填写的工程名上点击右键,选择生成自定义,然后选择masm项,确定。\r\n

\r\n

\r\n 6.选择lib库:在你填写的工程名上点击右键,选择属性,打开工程属性页,点击配置属性树形列表,点击连接器项,在右边属性的额外库属性中添加额外库,就是你所安装的masm32程序的lib 文件夹目录。\r\n

\r\n

\r\n 7.添加文件,选择cpp,但是名字用.asm,啥原因?自己想!另外一定要先搞这步,不然后面的微软宏汇编项找不着。\r\n

\r\n

\r\n 8.选择include:在你填写的工程名上点击右键,选择属性,打开工程属性页,点击配置属性树形列表,点击下面的微软宏汇编项,在其中的include path中填入你安装masm32程序的include文件夹目录。\r\n

\r\n

\r\n 9.最后,子系统选项:这个我就不管了,是console就选console,是windows就选windows,要是你用汇编写了一个windows程序,非要用console,那你程序后面出现个很讨厌的黑色命令框,你可别怨我,概不负责。提示:在属性页,系统选项下。\r\n

\r\n

\r\n 10.最最后,写代码啊,编译啊,执行啊。\r\n

\r\n

\r\n 11.代码高亮:\r\n

\r\n

\r\n (1)下载usertype.dat\r\n

\r\n

\r\n 下载地址:usertype.dat\r\n

\r\n

\r\n 放到C:Program FilesMicrosoft Visual Studio 10.0Common7IDE 目录。\r\n

\r\n

\r\n (2)打开工具->选项->文本编辑器->文件扩展名,添加asm,选择使用Microsoft Visual C++打开。重启VS2010,代码就高亮了。\r\n

\r\n
\r\n

\r\n 一个例子:
\r\n

\r\n
\r\n
\r\n
    \r\n
  1. \r\n .386  \r\n
  2. \r\n
  3. \r\n   \r\n
  4. \r\n
  5. \r\n .model flat, stdcall  \r\n
  6. \r\n
  7. \r\n   \r\n
  8. \r\n
  9. \r\n option casemap :none  \r\n
  10. \r\n
  11. \r\n   \r\n
  12. \r\n
  13. \r\n include windows.inc  \r\n
  14. \r\n
  15. \r\n   \r\n
  16. \r\n
  17. \r\n include kernel32.inc  \r\n
  18. \r\n
  19. \r\n   \r\n
  20. \r\n
  21. \r\n include user32.inc  \r\n
  22. \r\n
  23. \r\n   \r\n
  24. \r\n
  25. \r\n includelib kernel32.lib  \r\n
  26. \r\n
  27. \r\n   \r\n
  28. \r\n
  29. \r\n includelib user32.lib  \r\n
  30. \r\n
  31. \r\n   \r\n
  32. \r\n
  33. \r\n .data  \r\n
  34. \r\n
  35. \r\n   \r\n
  36. \r\n
  37. \r\n HelloWorld db\"HelloWorld!\"0  \r\n
  38. \r\n
  39. \r\n   \r\n
  40. \r\n
  41. \r\n .code  \r\n
  42. \r\n
  43. \r\n   \r\n
  44. \r\n
  45. \r\n start:  \r\n
  46. \r\n
  47. \r\n   \r\n
  48. \r\n
  49. \r\n invoke MessageBoxA, NULL, addrHelloWorld, addr HelloWorld, MB_OK  \r\n
  50. \r\n
  51. \r\n   \r\n
  52. \r\n
  53. \r\n invoke ExitProcess, 0  \r\n
  54. \r\n
  55. \r\n   \r\n
  56. \r\n
  57. \r\n end start 
    \r\n
    \r\n
  58. \r\n
\r\n
\r\n
\r\n
\r\n

\r\n 视频教程:\r\n

\r\n

\r\n http://wenku.baidu.com/course/study/4c4e51e2524de518964b7d91\r\n

\r\n

\r\n
\r\n

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2761, 'java-io-stream', 'Java中的IO流分类详解', '2013-05-05 15:30:23', '2019-03-25 21:29:22', '
\r\n

本文转载自:http://www.cnblogs.com/mengdd/archive/2013/02/11/2910143.html,略有改动。

\r\n
\r\n

流的概念

\r\n

  Java程序通过流来进行输入/输出。

\r\n

  流是生产或消费信息的抽象。

\r\n

  流通过Java的输入输出系统与物理设备链接。

\r\n

  尽管物理设备不尽相同,但是所有流的行为具有同样的方式。

\r\n

  这样,相同的输入/输出类和方法适用于所有类型的外部设备。这意味着,一个输入流能够抽象多种类型的输入:从磁盘文件、从键盘或从网络套接字;同样,一个输出流可以输出到:控制台、磁盘文件或相连的网络。处理输入输出不需要代码理解键盘和网络的不同。

\r\n

  Java中流的实现是在java.io包定义的类层次结构内部的。

\r\n

 

\r\n

输入/输出流概念

\r\n

  输入/输出时,数据在通信通道中流动。

\r\n

  所谓“数据流stream”指的是所有数据通信通道之中,数据的起点和终点。信息的通道就是一个数据流。只要是数据是从一个地方流到另一个地方,这种数据流动的通道都可以称为数据流

\r\n

 

\r\n

  输入/输出是相对于程序来说的,程序在使用数据时所扮演的角色有两个:一个是,一个是目的

\r\n

  若程序是数据流的源,即数据的提供者,这个数据流相对于程序来说就是一个“输出数据流”(数据从程序流出);若程序是数据流的终点,这个数据流对程序而言就是一个“输入数据流”(数据从程序外流向程序)。

\r\n

 

\r\n

输入/输出类

\r\n

  在java.io包中提供了60多个类(流)。

\r\n

  从功能上分为两大类:输入流和输出流。

\r\n

  从流结构上可分为字节流(Byte Streams,以字节为处理单位或称面向字节)和字符流(Character Streams,以字符为处理单位或称面向字符)。

\r\n

  字节流的输入流和输出流基础是InputStreamOutputStream这两个抽象类,字节流的输入输出操作由这两个类的子类实现。

\r\n

  字符流是Java 1.1版后新增加的以字符为单位进行输入输出处理的流,字符流输入输出的基础是抽象类ReaderWriter

\r\n

  在最底层,所有的输入/输出都是字节形式的。基于字符的流只为处理字符提供方便有效的方法。

\r\n

 

\r\n

输入流和输出流的处理逻辑

\r\n

 

\r\n

读数据的逻辑为:

\r\n

  open a stream

\r\n

  while more information

\r\n

  read information

\r\n

  close the stream

\r\n

 

\r\n

写数据的逻辑为:

\r\n

  open a stream

\r\n

  while more information

\r\n

  write information

\r\n

  close the stream

\r\n

 

\r\n

另一种流的分类

\r\n

  节点流:从特定的地方读写的流类。例如,磁盘或一块内存区域。

\r\n

  过滤流:使用节点流作为输入或输出。过滤流是使用一个已经存在的输入流或输出流连接创建的。

\r\n

  与目标相连的一定是节点流。

\r\n

 

\r\n

InputStream

\r\n

  三个基本的读方法:

\r\n

  abstract int read()

\r\n

  抽象方法,所以InputStream是一个抽象类。读取输入流的下一个字节数据,并返回读到的数据,如果返回-1,表示读到了输入流的末尾。

\r\n

  int read(byte[] b)

\r\n

  从输入流读入一些字节数据,把它们放进一个数组b,返回实际读取的字节数,如果返回-1,表示读到了输入流的末尾。

\r\n

  int read(byte[] b, int off, int len)

\r\n

  将数据读入一个字节数组,同时返回实际读取的字节数。如果返回-1,表示读到了输入流的末尾。off指定在数组b中存放数据的起始偏移位置;len指定读取的最大字节数。

\r\n

  为什么只有第一个read方法是抽象的,而其余两个read方法都是具体的?

\r\n

  因为第二个read方法依靠第三个read方法来实现,而第三个read方法又依靠第一个read方法来实现。所以说只有第一个read方法是与具体的I/O设备相关的,它需要InputStream的子类来实现。

\r\n

实例

\r\n
InputStream例子——从文件输入\r\n\r\nimport java.io.FileInputStream;\r\nimport java.io.IOException;\r\nimport java.io.InputStream;\r\n\r\npublic class InputStreamTest1\r\n{\r\n\r\n    public static void main(String[] args) throws IOException\r\n    {\r\n        InputStream is = new FileInputStream(\"d:/test.txt\");\r\n\r\n        byte[] buffer = new byte[200];\r\n\r\n        int length = 0;\r\n\r\n        while (-1 != (length = is.read(buffer, 0, 200)))\r\n        {\r\n            // 将字节数组转换成字符串\r\n            String str = new String(buffer, 0, length);\r\n            System.out.println(str);\r\n        }\r\n\r\n        // 将流所关联到的资源关闭\r\n        is.close();\r\n    }\r\n}
\r\n

 

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2762, 'js-compatible', 'JS强制使用兼容性视图', '2013-05-03 11:32:15', '2019-03-25 21:29:22', '

      只需在Html的Head标签<title></title>下面第一条加上下面一段代码即可。

\r\n
\r\n
    \r\n
  1. <meta http-equiv=\"X-UA-Compatible\" content=\"IE=EmulateIE7\" /  
  2. \r\n
\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2763, 'csharp-html-to-pdf', 'C#和ASP .NET将HTML生成PDF', '2013-04-26 20:43:09', '2019-03-25 21:29:22', '
\r\n

本文转载自http://www.cnblogs.com/shanyou/archive/2012/09/07/2676026.html,略有改动。

\r\n
\r\n

使用wkhtmtopdf(GPL协议)可以省很多程序代码, 首先到官网http://code.google.com/p/wkhtmltopdf/downloads/list,找installer.exe下载  

\r\n

wkhtmltopdf,一个集成好了的exe文件(C++编写),基本的调用方法是:

\r\n

C:Softwkhtmltopdfwkhtmltopdf.exe http://www.xinvalue.com D:terwer.pdf

\r\n

\"\"

\r\n

     可以先在命令行测试一下,有其他的需要可以在命令行通过wkhtmltopdf --help查询,如果是超长页的花,可以用命令

\r\n

C:Softwkhtmltopdfwkhtmltopdf.exe http://www.xinvalue.com D:terwer.pdf  -H --outline (-H是添加默认标题,--outline是添加pdf的左侧概要哦!)而且可以批量生成哦,中间用空格隔开)。

\r\n

  C#调用测试,建立一个ASP .NET测试Web页,添加一个Button,在click事件中加入如下代码:

\r\n
\r\n

代码

\r\n
\r\n
    \r\n
  1. //因为Web 是多线程环境,避免甲产生的文件被乙下载去,所以档名都用唯一  
  2. \r\n
  3.   
  4. \r\n
  5.          string fileNameWithOutExtention = Guid.NewGuid().ToString();  
  6. \r\n
  7.          //执行wkhtmltopdf.exe   
  8. \r\n
  9.          Process p = System.Diagnostics.Process.Start(@\"C:Softwkhtmltopdfwkhtmltopdf.exe\", @\"http://www.xinvalue.com D:\" +fileNameWithOutExtention + \".pdf\"); 
  10. \r\n
  11.          //若不加这一行,程序就会马上执行下一句而抓不到文件发生意外:System.IO.FileNotFoundException: 找不到文件 \'\'。 
  12. \r\n
  13.          p.WaitForExit(); 
  14. \r\n
  15.          //把文件读进文件流 
  16. \r\n
  17.          FileStreamf s = newFileStream(@\"D:\" + fileNameWithOutExtention + \".pdf\", FileMode.Open); 
  18. \r\n
  19.          byte[] file = newbyte[fs.Length]; 
  20. \r\n
  21.          fs.Read(file, 0, file.Length); 
  22. \r\n
  23.          fs.Close(); 
  24. \r\n
  25.  
  26. \r\n
  27.          //Response给客户端下载 
  28. \r\n
  29.  
  30. \r\n
  31.          Response.Clear(); 
  32. \r\n
  33.          Response.AddHeader(\"content-disposition\", \"attachment; filename=\" +fileNameWithOutExtention + \".pdf\");//强制下载 
  34. \r\n
  35.          Response.ContentType = \"application/octet-stream\";   
  36. \r\n
  37.          Response.BinaryWrite(file);   
  38. \r\n
\r\n
\r\n
\r\n

 

\r\n

在GitHub上发现2个相关的项目,其中Pechkin这个项目不需要单独安装wkhtmltopdf ,就是.NET的库了。

\r\n

C# wrapper around excellent wkhtmltopdf console utility  https://github.com/codaxy/wkhtmltopdf

\r\n

.NET Wrapper for WkHtmlToPdf static DLL. Allows you to utilize full power of the libra:https://github.com/gmanny/Pechkin

\r\n

 

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2764, 'firefox-goagent-autoproxy', 'goagent配合Firefox和autoproxy翻墙教程(Windows版)', '2013-11-12 14:00:00', '2019-03-25 21:29:22', '

\r\n 【版权声明:本文转载自网易博客,版权归原作者。如需转载,请务必在转载时注明原文地址。】\r\n

\r\n
\r\n

\r\n 粗略的来讲分为三个步骤\r\n

\r\n

\r\n (1)申请Google App Engine账号,创建ID\r\n

\r\n

\r\n (2)更改goagent客户端配置\r\n

\r\n

\r\n (3)设置autoproxy\r\n

\r\n

\r\n 一、首先申请Google App Engine账号(俗称GAE,其实就是Google账号)\r\n

\r\n

\r\n 网址是\r\n

\r\nhttp://appengine.google.com登陆,然后如图点击创建,填写APPID,最后申请成功,记住APP ID\r\n

\r\n 二、goagent客户端配置\r\n

\r\n

\r\n 下载地址(地址可能不太稳定):\r\n

\r\n

\r\n https://code.google.com/p/goagent/
\r\n\r\n

\r\n如果不稳定,可以点击下面百度云地址:
\r\n
\r\n

\r\n goahent-2.17\r\n

\r\n

\r\n 下完后解压,有两个文件夹\r\n

\r\n

\r\n 双击serveruploader.bat,输入你的APPID和你的用户名密码(Google账号),上传服务端\r\n

\r\n

\r\n \"ga5\"\r\n

\r\n

\r\n 然后打开记事本,修改local文件夹下的proxy.ini里面的APPID\r\n

\r\n

\r\n \"ga6\"\r\n

\r\n

\r\n  \r\n

\r\n

\r\n 三、设置autoproxy\r\n

\r\n

\r\n 下载地址\r\n

\r\n

\r\n https://addons.mozilla.org/zh-cn/firefox/addon/autoproxy/\r\n

\r\n

\r\n 或者直接点击安装\r\n

\r\n

\r\n https://addons.mozilla.org/firefox/downloads/latest/11009/addon-11009-latest.xpi?src=dp-btn-primary\r\n

\r\n

\r\n 安装后,订阅规则\r\n

\r\n

\r\n 然后\r\n

\r\n

\r\n 代理服务器→编辑代理服务器,新建一个为goagent,端口为8087,选择代理服务器为goagent\r\n

\r\n\"ga3\"\r\n

\r\n  \r\n

\r\n

\r\n \"ga4\"\r\n

\r\n

\r\n 导入证书\r\n

\r\n

\r\n 选项→高级→加密→查看证书→导入local下的CA.crt\r\n

\r\n\"ga\"\r\n

\r\n  \r\n

\r\n

\r\n \"ga2\"\r\n

\r\n

\r\n 一切设置完毕!\r\n

\r\n

\r\n 最后打开local下的proxy.exe就可以了。\r\n

\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2765, '360-2', '屏蔽JS加载错误', '2013-04-24 12:34:31', '2019-03-25 21:29:22', '
/*屏蔽JS加载错误*/\r\n<script type=\"text/javascript\">\r\nwindow.onerror = function() {\r\nreturn true;\r\n};\r\n</script>\r\n/*屏蔽JS加载错误*/

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2766, '355-2', '.net异步中文乱码', '2013-04-18 21:57:21', '2019-03-25 21:29:22', '

本文参考自百度知道,原文地址:http://zhidao.baidu.com/question/375292307.html,略有改动。

问题:

.net异步中文乱码

解决方案:

编码格式变为gb2312

在Web.config中做如下修改:

<system.web>\r\n<globalization fileEncoding=\"gb2312\" requestEncoding=\"gb2312\" responseEncoding=\"gb2312\" culture=\"zh-CN\"/>\r\n</system.web>


', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2767, '348', '三元组的算法实现(C语言)', '2013-04-16 13:41:44', '2019-03-25 21:29:22', '
#include <stdio.h>
#include <stdlib.h>
 
#define OVERFLOW -2
#define OK 1
 
typedef int ElemType;
typedef ElemType* Triplet;
 
void InitTriplet(Triplet *T,ElemType v1,ElemType v2,ElemType v3)
{
 
   (*T)=(Triplet)malloc(3*sizeof(ElemType));
   if(!(*T))
   {
   exit(OVERFLOW);
   }
 
    (*T)[0]=v1;
    (*T)[1]=v2;
    (*T)[2]=v3;
}
 
int DestroyTriplet(Triplet T)
{
   free(T);
   T=NULL;
   returnOK;
}
 
ElemType GetElem(Triplet T,int i)
{
returnT[i-1];
}
 
void PutElem(Triplet T,int i,ElemType e)
{
T[i-1]=e;
}
 
 
ElemType Max(Triplet T)
{
   ElemType maxValue;
   if(T[0]>T[1]){
   maxValue=T[0];
   }
 
   else{
 
   maxValue=T[1];
   }
 
   if(maxValue<T[2])
   {
       maxValue=T[2];
   }
   return maxValue;
}
 
ElemType Min(Triplet T)
{
   ElemType minValue;
   if(T[0]<T[1])
   {
       minValue=T[0];
   }
   else{
   minValue=T[1];
   }
 
   if(minValue>T[2])
   {
       minValue=T[2];
   }
 
   return minValue;
}
 
 
 
void Asc(Triplet T)
{
     
   if(T[0]>T[1])
   {
       ElemType temp;
       temp=T[0];
       T[0]=T[1];
       T[1]=temp;
   }
     
   if(T[1]>T[2])
   {
       ElemType temp3;
       temp3=T[1];
       T[1]=T[2];
       T[2]=temp3;
   }
     
   if(T[0]>T[1])
   {
       ElemType temp3;
       temp3=T[0];
       T[0]=T[1];
       T[1]=temp3;
   }
}
 
 
void Desc(TripletT)
{
   if(T[0]<T[1]){
       ElemType temp;
       temp=T[0];<\r\n/span>
       T[0]=T[1];
       T[1]=temp;
   }
   if(T[0]<T[2]){
       ElemType temp2;
       temp2=T[0];
       T[0]=T[2];
       T[2]=temp2;
   }
   if (T[1]<T[2])
   {
       ElemType temp3;
       temp3=T[1];
       T[1]=T[2];
       T[2]=temp3;
   }
}
 
int main()
{
   Triplett1=NULL;
   InitTriplet(&t1,2,1,6);
 
   printf("%d %d %dn",t1[0],t1[1],t1[2]);  
   Desc(t1);
   printf("%d %d %dn",t1[0],t1[1],t1[2]);
   return 0;
}


', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2768, '342', '数据结构中的时间复杂度规则', '2013-04-16 13:36:39', '2019-03-25 21:29:22', '

时间复杂度的规则

一般规则

a)  加法规则

T(n)=T1(n)+T2(n)=O(f(n))+O(g(n))=O(max(f(n),g(n)))

b)  乘法规则

T(n)=T1(n)*T2(n)=O(f(n))*O(g(n))=O(f(n)*g(n))

常见的渐进时间复杂度

O(1)<O(log2n)<O(n)<O(nlog2n)<O(n^2)<O(n^3)<O(2^n)<O(n!)<O(n^n)


', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2769, '333-2', 'Win2003无线网卡驱动无法安装解决方法', '2013-04-16 13:24:30', '2019-03-25 21:29:22', '

本文转载自:http://www.jb51.net/os/windows/Win2003/75344.html,略有改动。

Lenovo B470笔记本内置atheros ar5b97无线网卡,在Windows Server 2003操作系统下不能启动,使用驱动精灵2012安装最新ar5b97驱动程序后在设备管理器中始终显示黄色感叹号。

产生这个问题的原因是Windows 2003 Server对无线网卡的pci资源分配出了问题,而笔记本bios中屏蔽了pci配置项,无法修改
要解决这个问题,有的人选择更换支持的无线网卡,其实不用更换无线网卡,
解决方法如下

打开资源管理器菜单,工具-文件夹选项-显示,去掉“隐藏受保护的操作系统文件”选项前的对号,打开C盘根目录,右键boot.ini文件属性,去掉只读属性。打开boot.ini文件,内容如下:

[boot loader]\r\ntimeout=30\r\ndefault=multi(0)disk(0)rdisk(0)partition(1)WINDOWS\r\n[operating systems]\r\nmulti(0)disk(0)rdisk(0)partition(1)WINDOWS=\"Windows Server 2003,Enterprise\" /noexecute=optout /fastdetect

把其中noexecute=optout 项改为execute=optin,保存修改,恢复boot.ini只读属性,恢复隐藏受保护的操作系统文件。重新启动计算机进入设备管理器即可看到,无线网卡已经启用了!可右键屏幕右下WiFi信号标志,选择客户端软件,可选择使用Atheros客户端使用程序或Windows管理无线网卡,一般选择使用windows管理。查看可用的无线网络,选择网络,输入连接密码,即可联网了!


', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2771, '321-2', '解决Win2003下IIS无法访问到FLV文件的问题(提示404)', '2013-04-16 12:56:30', '2019-03-25 21:29:22', '

本文转载自:http://www.cnblogs.com/martin1009/archive/2012/05/11/2496039.html,略有改动。


今天为为一个网站项目添加在线视频(FLV格式)播放功能结果试了好多次均无发加载到视频,以为地址出错了,进入服务器,看看路径没问题……直接访问flv文件,汗死,浏览器提示404……


百度一番,终于找到问题:由于windows server 2003上并没有.FLV的这种mime-type类型,需要手工添加。


解决方法:

1、打开Internet 信息服务(IIS)管理器;

2、右击选择属性->MIME 类型->MIME 类型

3、打开MIME 类型->点“新建”;

4、输入扩展名:.flv     MIME类型:flv-application/octet-stream

5、确定-确定-确定;

6、在CMD种->iisreset。


测试发现可以正常播放FLV视频了。

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2772, '316', '软件质量保证与测试学习笔记(一)-软件质量的概念', '2013-04-16 11:10:35', '2019-03-25 21:29:22', '

1、质量:系统、过程和部件满足明确需求。

2、软件质量:软件产品满足使用需求的程度。

3、几种质量模型

(1)MaCall质量模型操作特性、承受可改变能力、新环境适应能力。

(2)Boehm质量模型

特点:分层结构,同时包含用户需求和硬件特性。

(3)ISO/IEC9126质量模型分为三个部分:内部质量模型、外部质量模型、使用中质量模型。

(4)几个名词:

软件缺陷(Bug)

失效(failure)

矛盾(inconsistency)

缺点(defect)

偏差(variance)

缪误(fault)

错误(error)

问题(problem)

毛病(incident)

异常(anomy)

定义:软件缺陷是软件在生命周期内的各个阶段出现的不满足给定的需求属性的问题。

\r\n(5)软件说明书的分类:\r\n需求规格说明书、设计说明书、产品使用说明书、用户手册等。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2773, '315', '20131215044748', '2013-04-16 16:10:30', '2019-03-25 21:29:22', '一个人,只有有梦想的活着,才能不虚度光阴。\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2774, 'ckediror-to-ueditor', '从CKEditor转到UEditor的使用心得', '2013-04-15 12:34:24', '2019-03-25 21:29:22', '

之前一直用的CKEditor(神马?不知道是什么,自己百度百科)来作为文章编辑器,说实话,在Web编辑器上,ckeditor确实不错,不过因为这是老外的产品,虽然做的很优秀,但本地化却有些不太好。

\r\n

还是简要介绍一下吧,CKEditor是国外一款非常优秀的富文本编辑器,官网是http://www.cksource.com,而今天我要说的UEditor也是富文本编辑器,不过他是国产的,百度旗下的一款开源免费产品,官网http://ueditor.baidu.com/website/。

\r\n

其实本地化的问题这并不是我从CKEditor转向UEditor的原因,主要原因是,最近再做招生办的一个项目(具体的不方便透露哈),需要发表文章功能,老师们一般是在Word里面写好了文章,然后再粘贴到网页中的,并且要保留原始格式,但是不幸的是CKEditor默认清楚了所有的Word格式,这就很头痛。虽然在网上找到了一些解决方案,但效果还是不太理想,Word问题是基本解决了,但是一旦发表复杂的表格时,表格又变形了,很难看!哎!没办法,还好之前对UEditor略有耳闻,今天不放一试,后来发现果然很不错,格式保留的相当完美。于是就开始在官网下载了源码,开始研究。

\r\n

老实说,其实CKeditor使用起来还是很方便的,初一接触UEditor还真不知从何下手,扫了一眼刚下载的文件,有个_examples目录,对,就从他下手。

\r\n

于是在VS上建了一个项目,先测试测试吧,运行项目,打开_example里面的index.html:
代码如下:

\r\n
\r\n
 
\r\n
    \r\n
  1. <!DOCTYPE HTML>     
  2. \r\n
  3. <html>     
  4. \r\n
  5. <head>     
  6. \r\n
  7. <metahttp-equivmetahttp-equivmetahttp-equivmetahttp-equiv=\"Content-Type\"content=\"text/html;charset=utf-8\"/>     
  8. \r\n
  9.  <title></title>       
  10. \r\n
  11.    <scripttypescripttypescripttypescripttype=\"text/javascript\"charset=\"utf-8\"src=\"../editor_config.js\"></script>     
  12. \r\n
  13.    <!--使用版-->     
  14. \r\n
  15.    <!--<script type=\"text/javascript\" charset=\"utf-8\" src=\"../editor_all.js\"></script>-->     
  16. \r\n
  17.    <!--开发版-->     
  18. \r\n
  19.    <scripttypescripttypescripttypescripttype=\"text/javascript\"charset=\"utf-8\"src=\"editor_api.js\"></script>     
  20. \r\n
  21.    <styletypestyletypestyletypestyletype=\"text/css\">     
  22. \r\n
  23.        #myEditor{     
  24. \r\n
  25.            width: 500px;     
  26. \r\n
  27.            height: 300px;     
  28. \r\n
  29.        }     
  30. \r\n
  31.    </style>     
  32. \r\n
  33. </head>     
  34. \r\n
  35. <body>     
  36. \r\n
  37.    <h1>文本域渲染编辑器</h1>     
  38. \r\n
  39.    <!--style给定宽度可以影响编辑器的最终宽度-->     
  40. \r\n
  41.    <textareaidtextareaidtextareaidtextareaid=\"myEditor\">这里是原始的textarea中的内容,可以从数据中读取</textarea>     
  42. \r\n
  43.    <br/>     
  44. \r\n
  45.    <inputtypeinputtypeinputtypeinputtype=\"button\"onclick=\"render()\"value=\"渲染编辑器\">     
  46. \r\n
  47.    <scripttypescripttypescripttypescripttype=\"text/javascript\">     
  48. \r\n
  49.        //渲染编辑器     
  50. \r\n
  51.        function render() {     
  52. \r\n
  53.            UE.getEditor(\'myEditor\');     
  54. \r\n
  55.        }     
  56. \r\n
  57.    </script>     
  58. \r\n
  59. </body>     
  60. \r\n
  61. </html>   
  62. \r\n
\r\n

这个demo有很多例子,由于我现在要用文本域,所以我先研究了下文本域,我仔细看了下代码,其实调用还是挺简单的。先在head里面加上JS引用,然后再调用相关方法渲染即可。接下来,我来自己实现,可是新建了个aspx文件之后,JS也应用了,可就是不显示,后来折腾了半天,发现是路径问题,需要在editor_config.js文件中把window.UEDITOR_HOME_URL 设置成ueditor所在的路径,否则将会报错:

\r\n

以下是我写的测试代码(UEditorTest.aspx):

\r\n

测试代码:

\r\n
\r\n
 
\r\n
    \r\n
  1. <%@ Page Language=\"C#\" AutoEventWireup=\"true\" CodeBehind=\"Test.aspx.cs\" Inherits=\"UEditorTest.Test\" %>    
  2. \r\n
  3. <!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">    
  4. \r\n
  5. <html>    
  6. \r\n
  7.  <headrunatheadrunatheadrunatheadrunat=\"server\">    
  8. \r\n
  9.        <title>我的UEditor初体验</title>      
  10. \r\n
  11.        <!--UEditor-->      <scriptsrcscriptsrcscriptsrcscriptsrc=\"ueditor/editor_config.js\"type=\"text/javascript\">     
  12. \r\n
  13. </script>       <scriptsrcscriptsrcscriptsrcscriptsrc=\"ueditor/editor_all.js\"type=\"text/javascript\">     
  14. \r\n
  15. </script>    
  16. \r\n
  17.        <!--UEditor-->    
  18. \r\n
  19.        <scriptsrcscriptsrcscriptsrcscriptsrc=\"JS/jquery-1.3.2.js\"type=\"text/javascript\">    
  20. \r\n
  21.  </script>    
  22. \r\n
  23.        <!--屏蔽JS加载错误-->    
  24. \r\n
  25.        <scripttypescripttypescripttypescripttype=\"text/javascript\"> window.onerror = function()     
  26. \r\n
  27. { return true; }; </script>    
  28. \r\n
  29.        <!--屏蔽JS加载错误-->    
  30. \r\n
  31.    </head>    
  32. \r\n
  33.    <body>    
  34. \r\n
  35.        <formidformidformidformid=\"form1\"runat=\"server\">         <asp:TextBoxIDasp:TextBoxIDasp:TextBoxIDasp:TextBoxID=\"txtContent\"TextMode=\"MultiLine\"    
  36. \r\n
  37. Text=\"LeaveBugsAway\"runat=\"server\"></asp:TextBox>    
  38. \r\n
  39.            <!--渲染编辑器-->    
  40. \r\n
  41.            <scripttypescripttypescripttypescripttype=\"text/javascript\">    
  42. \r\n
  43.                var myEditor = document.getElementById(\"<%= txtContent.ClientID %>\");    
  44. \r\n
  45.                UE.getEditor(myEditor);    
  46. \r\n
  47.            </script>      <asp:buttonIDasp:buttonIDasp:buttonIDasp:buttonID=\"Button1\"runat=\"server\"text=\"提交\"/>    
  48. \r\n
  49.        </form>    
  50. \r\n
  51.    </body>    
  52. \r\n
  53. </html>   
  54. \r\n
\r\n

特别注意:如果使用的是TextBox,一定要设置TextMode=\"MultiLine\"这是因为UEditor渲染的是Textarea,而TextBox只有设置成TextMode=\"MultiLine\"才会生成textarea。如果大家还有问题,欢迎留言,我会尽量回答。

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2775, '2013-4-14-07-26', '20131218192005', '2013-04-15 15:30:21', '2019-03-25 21:29:22', '一个人只有三种东西是别人抢不走的,吃进胃里的食物,藏在心中的梦想,读在脑子里的书。\r\n\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2776, '243-2', 'Java中的synchronized详解', '2013-04-11 12:14:55', '2019-03-25 21:29:22', '

本文转载自:http://www.cnblogs.com/devinzhang/archive/2011/12/14/2287675.html,略有改动。

synchronized是Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。以下是笔者几点使用心得,现与大家一起交流一下:

一、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。

二、然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块

三、尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。

四、第三个例子同样适用其它同步代码块。也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞

五、以上规则对其它对象锁同样适用。

以上是关于synchronized的基础讲解,下面我们进行更加深入的分析:

synchronized关键字,它包括两种用法:synchronized 方法 synchronized 块
1. synchronized 方法:通过在方法声明中加入 synchronized关键字来声明 synchronized 方法。如:
public synchronized void accessVal(int newVal);
synchronized 方法控制对类成员变量的访问:每个类实例对应一把锁,每个 synchronized 方法都必须获得调用该方法的类实例的锁方能

执行,否则所属线程阻塞,方法一旦执行,就独占该锁,直到从该方法返回时才将锁释放,此后被阻塞的线程方能获得该锁,重新进入可执行

状态。这种机制确保了同一时刻对于每一个类实例,其所有声明为 synchronized 的成员函数中至多只有一个处于可执行状态(因为至多只有

一个能够获得该类实例对应的锁),从而有效避免了类成员变量的访问冲突(只要所有可能访问类成员变量的方法均被声明为 synchronized)


在 Java 中,不光是类实例,每一个类也对应一把锁,这样我们也可将类的静态成员函数声明为 synchronized ,以控制其对类的静态成

员变量的访问。
synchronized 方法的缺陷:若将一个大的方法声明为synchronized 将会大大影响效率,典型地,若将线程类的方法 run() 声明为

synchronized ,由于在线程的整个生命期内它一直在运行,因此将导致它对本类任何 synchronized 方法的调用都永远不会成功。当然我们可

以通过将访问类成员变量的代码放到专门的方法中,将其声明为 synchronized ,并在主方法中调用来解决这一问题,但是 Java 为我们提供

了更好的解决办法,那就是 synchronized 块。

2. synchronized 块:通过 synchronized关键字来声明synchronized 块。语法如下:
synchronized(syncObject) {
//允许访问控制的代码
}
synchronized 块是这样一个代码块,其中的代码必须获得对象 syncObject (如前所述,可以是类实例或类)的锁方能执行,具体机

制同前所述。由于可以针对任意代码块,且可任意指定上锁的对象,故灵活性较高。
最后,我们队java中synchronized进行一个通俗解释:

打个比方:一个object就像一个大房子,大门永远打开。房子里有 很多房间(也就是方法)。

这些房间有上锁的(synchronized方法), 和不上锁之分(普通方法)。房门口放着一把钥匙(key),这把钥匙可以打开所有上锁的房间。

另外我把所有想调用该对象方法的线程比喻成想进入这房子某个 房间的人。所有的东西就这么多了,下面我们看看这些东西之间如何作用的。

在此我们先来明确一下我们的前提条件。该对象至少有一个synchronized方法,否则这个key还有啥意义。当然也就不会有我们的这个主题了。

一个人想进入某间上了锁的房间,他来到房子门口,看见钥匙在那儿(说明暂时还没有其他人要使用上锁的房间)。于是他走上去拿到了钥匙

,并且按照自己 的计划使用那些房间。注意一点,他每次使用完一次上锁的房间后会马上把钥匙还回去。即使他要连续使用两间上锁的房间,

中间他也要把钥匙还回去,再取回来。

因此,普通情况下钥匙的使用原则是:“随用随借,用完即还。”

这时其他人可以不受限制的使用那些不上锁的房间,一个人用一间可以,两个人用一间也可以,没限制。但是如果当某个人想要进入上锁的房间,他就要跑到大门口去看看了。有钥匙当然拿了就走,没有的话,就只能等了。

要是很多人在等这把钥匙,等钥匙还回来以后,谁会优先得到钥匙?Not guaranteed。象前面例子里那个想连续使用两个上锁房间的家伙,他

中间还钥匙的时候如果还有其他人在等钥匙,那么没有任何保证这家伙能再次拿到。 (JAVA规范在很多地方都明确说明不保证,象

Thread.sleep()休息后多久会返回运行,相同优先权的线程那个首先被执行,当要访问对象的锁被 释放后处于等待池的多个线程哪个会优先得

到,等等。我想最终的决定权是在JVM,之所以不保证,就是因为JVM在做出上述决定的时候,绝不是简简单单根据 一个条件来做出判断,而是

根据很多条。而由于判断条件太多,如果说出来可能会影响JAVA的推广,也可能是因为知识产权保护的原因吧。SUN给了个不保证 就混过去了

。无可厚非。但我相信这些不确定,并非完全不确定。因为计算机这东西本身就是按指令运行的。即使看起来很随机的现象,其实都是有规律

可寻。学过计算机的都知道,计算机里随机数的学名是伪随机数,是人运用一定的方法写出来的,看上去随机罢了。另外,或许是因为要想弄

的确定太费事,也没多大意义,所 以不确定就不确定了吧。)

再来看看同步代码块。和同步方法有小小的不同。

1.从尺寸上讲,同步代码块比同步方法小。你可以把同步代码块看成是没上锁房间里的一块用带锁的屏风隔开的空间。

2.同步代码块还可以人为的指定获得某个其它对象的key。就像是指定用哪一把钥匙才能开这个屏风的锁,你可以用本房的钥匙;你也可以指定

用另一个房子的钥匙才能开,这样的话,你要跑到另一栋房子那儿把那个钥匙拿来,并用那个房子的钥匙来打开这个房子的带锁的屏风。

记住你获得的那另一栋房子的钥匙,并不影响其他人进入那栋房子没有锁的房间。

为什么要使用同步代码块呢?我想应该是这样的:首先对程序来讲同步的部分很影响运行效率,而一个方法通常是先创建一些局部变

量,再对这些变量做一些 操作,如运算,显示等等;而同步所覆盖的代码越多,对\r\n效率的影响就越严重。因此我们通常尽量缩小其影响范围。

如何做?同步代码块。我们只把一个方法中该同 步的地方同步,比如运算。

另外,同步代码块可以指定钥匙这一特点有个额外的好处,是可以在一定时期内霸占某个对象的key。还记得前面说过普通情况下钥

匙的使用原则吗。现在不是普通情况了。你所取得的那把钥匙不是永远不还,而是在退出同步代码块时才还。

还用前面那个想连续用两个上锁房间的家伙打比方。怎样才能在用完一间以后,继续使用另一间呢。用同步代码块吧。先创建另外

一个线程,做一个同步代码 块,把那个代码块的锁指向这个房子的钥匙。然后启动那个线程。只要你能在进入那个代码块时抓到这房子的钥匙

,你就可以一直保留到退出那个代码块。也就是说 你甚至可以对本房内所有上锁的房间遍历,甚至再sleep(10*60*1000),而房门口却还有

1000个线程在等这把钥匙呢。很过瘾吧。

在此对sleep()方法和钥匙的关联性讲一下。一个线程在拿到key后,且没有完成同步的内容时,如果被强制sleep()了,那key还一

直在 它那儿。直到它再次运行,做完所有同步内容,才会归还key。记住,那家伙只是干活干累了,去休息一下,他并没干完他要干的事。为

了避免别人进入那个房间 把里面搞的一团糟,即使在睡觉的时候他也要把那唯一的钥匙戴在身上。

最后,也许有人会问,为什么要一把钥匙通开,而不是一个钥匙一个门呢?我想这纯粹是因为复杂性问题。一个钥匙一个门当然更

安全,但是会牵扯好多问题。钥匙 的产生,保管,获得,归还等等。其复杂性有可能随同步方法的增加呈几何级数增加,严重影响效率。这也

算是一个权衡的问题吧。为了增加一点点安全性,导致效 率大大降低,是多么不可取啊。

synchronized的一个简单例子:

publicclassTextThread {\r\n\r\npublicstaticvoidmain(String[] args) {\r\nTxtThread tt = newTxtThread();\r\nnewThread(tt).start();\r\nnewThread(tt).start();\r\nnewThread(tt).start();\r\nnewThread(tt).start();\r\n}\r\n}\r\n\r\nclassTxtThread implementsRunnable {\r\nintnum = 100;\r\nString str = newString();\r\n\r\npublicvoidrun() {\r\nsynchronized(str) {\r\nwhile(num > 0) {\r\n\r\ntry{\r\nThread.sleep(1);\r\n} catch(Exception e) {\r\ne.getMessage();\r\n}\r\nSystem.out.println(Thread.currentThread().getName()\r\n+ \"this is \"+ num--);\r\n}\r\n}\r\n}\r\n}

上面的例子中为了制造一个时间差,也就是出错的机会,使用了Thread.sleep(10)

Java对多线程的支持与同步机制深受大家的喜爱,似乎看起来使用了synchronized关键字就可以轻松地解决多线程共享数据同步问题。到底如

何?――还得对synchronized关键字的作用进行深入了解才可定论。

总的说来,synchronized关键字可以作为函数的修饰符,也可作为函数内的语句,也就是平时说的同步方法和同步语句块。如果再细的分类,

synchronized可作用于instance变量、object reference(对象引用)、static函数和class literals(类名称字面常量)身上。

在进一步阐述之前,我们需要明确几点:

A.无论synchronized关键字加在方法上还是对象上,它取得的锁都是对象,而不是把一段代码或函数当作锁――而且同步方法很可能还会被其

他线程的对象访问。

B.每个对象只有一个锁(lock)与之相关联。

C.实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制。

接着来讨论synchronized用到不同地方对代码产生的影响:

假设P1、P2是同一个类的不同对象,这个类中定义了以下几种情况的同步块或同步方法,P1、P2就都可以调用它们。

1. 把synchronized当作函数修饰符时,示例代码如下:

Public synchronized void methodAAA()

{

//….

}

这也就是同步方法,那这时synchronized锁定的是哪个对象呢?它锁定的是调用这个同步方法对象。也就是说,当一个对象P1在不同的线程中

执行这个同步方法时,它们之间会形成互斥,达到同步的效果。但是这个对象所属的Class所产生的另一对象P2却可以任意调用这个被加了

synchronized关键字的方法。

上边的示例代码等同于如下代码:

public void methodAAA()

{

synchronized (this)      // (1)

{

//…..

}

}

(1)处的this指的是什么呢?它指的就是调用这个方法的对象,如P1。可见同步方法实质是将synchronized作用于object reference。――那个

拿到了P1对象锁的线程,才可以调用P1的同步方法,而对P2而言,P1这个锁与它毫不相干,程序也可能在这种情形下摆脱同步机制的控制,造

成数据混乱:(

2.同步块,示例代码如下:

public void method3(SomeObject so)

{

synchronized(so)

{
//…..
}

}

这时,锁就是so这个对象,谁拿到这个锁谁就可以运行它所控制的那段代码。当有一个明确的对象作为锁时,就可以这样写程序,但当没有明

确的对象作为锁,只是想让一段代码同步时,可以创建一个特殊的instance变量(它得是一个对象)来充当锁:

class Foo implements Runnable

{

private byte[] lock = new byte[0]; // 特殊的instance变量

Public void methodA()
{

synchronized(lock) { //… }

}

//…..

}

注:零长度的byte数组对象创建起来将比任何对象都经济――查看编译后的字节码:生成零长度的byte[]对象只需3条操作码,而Object lock

= new Object()则需要7行操作码。

3.将synchronized作用于static 函数,示例代码如下:

Class Foo
{

public synchronized static void methodAAA()   // 同步的static 函数
{
//….
}

public void methodBBB()
{

synchronized(Foo.class)   // class literal(类名称字面常量)

}
}

代码中的methodBBB()方法是把class literal作为锁的情况,它和同步的static函数产生的效果是一样的,取得的锁很特别,是当前调用这

个方法的对象所属的类(Class,而不再是由这个Class产生的某个具体对象了)。

记得在《Effective Java》一书中看到过将 Foo.class和 P1.getClass()用于作同步锁还不一样,不能用P1.getClass()来达到锁这个Class的

目的。P1指的是由Foo类产生的对象。

可以推断:如果一个类中定义了一个synchronized的static函数A,也定义了一个synchronized 的instance函数B,那么这个类的同一对象Obj

在多线程中分别访问A和B两个方法时,不会构成同步,因为它们的锁都不一样。A方法的锁是Obj这个对象,而B的锁是Obj所属的那个Class。

小结如下:

搞清楚synchronized锁定的是哪个对象,就能帮助我们设计更安全的多线程程序。

还有一些技巧可以让我们对共享资源的同步访问更加安全:

1. 定义private 的instance变量+它的 get方法,而不要定义public/protected的instance变量。如果将变量定义为public,对象在外界可以绕过同步方法的控制而直接取得它,并改动它。这也是JavaBean的标准实现方式之一。

2. 如果instance变量是一个对象,如数组或ArrayList什么的,那上述方法仍然不安全,因为当外界对象通过get方法拿到这个instance对象的引用后,又将其指向另一个对象,那么这个private变量也就变了,岂不是很危险。 这个时候就需要将get方法也加上synchronized同步,并且,只返回这个private对象的clone()――这样,调用端得到的就是对象副本的引用了。


', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2777, 'office-2003-2010-perfect-solution-for-coexistence', 'office 2003 2010完美共存的解决方案', '2013-03-29 17:42:21', '2019-03-25 21:29:22', '

[copy]http://mtoou.info/office-2003-2010-gc/[/copy] 

\r\n

很多人现在用上了 MS Office 2010,但同时想保留以前安装的Office 2003,想office 2003 2010共存使用是件麻烦的事情。

\r\n

首先,安装Office2003再安装Office2010,最好安装在不同盘(在此我把Office2003安装在C盘,把Office2010安装在D盘),安装Office2010时选“自定义-保留较早版本安装”。安装完后根据自己喜好按顺序执行以下操作便可。

\r\n

1、让Excel2010和2003分别关联各自文件类型的方法:在运行里输入:

\r\n
\"C:Program FilesMicrosoft OfficeOFFICE11excel.exe\" /regserver
\r\n

2、让Powerpoint2010和2003分别关联各自文件类型的方法:在运行里输入:

\r\n
\"C:Program FilesMicrosoft OfficeOFFICE11powerpnt.exe\" /regserver
\r\n

3、让Word2010和2003分别关联各自文件类型的方法稍微麻烦些,如下:
(1)在运行里输入:

\r\n
\r\n

reg add HKCUSoftwareMicrosoftOffice11.0WordOptions /v NoReReg /t REG_DWORD /d 1

\r\n
\r\n

(2)在运行里输入:

\r\n
\r\n

reg add HKCUSoftwareMicrosoftOffice14.0WordOptions /v NoReReg /t REG_DWORD /d 1

\r\n
\r\n

(以上二个添加注册表值是为了让Word 2003和2010和谐共处,不再出现配置界面。)

\r\n

进入C:Program FilesMicrosoft OfficeOFFICE11文件夹,将WINWORD.exe改名为WINWORD11.exe。随意找到一个.doc文件,右键选择打开方式,浏览 到WINWORD11.exe,并勾选“始终使用选择的程序打开这种文件”后点确定。
备注:C:Program FilesMicrosoft OfficeOFFICE11这个路径为xp操作系统下默认的Office2003的安装路径,你的机子上可能不是这个路径。如果C盘下 MSOCahce文件夹不在了,可能需要读取Office2003安装光盘或解压到硬盘上的Office2003安装源。

\r\n

4、安装Office2003打开Office2007及更高版本文件的兼容包,来解决Office2003打开Office2007及更高版本文 件并使各版本word关联自己的文件(如果不进行关联,所有Office文档默认都是用后装的Office2010打开的,微软官方网站有下载)

\r\n

5、为Office2010文档在右键菜单里添加“用Office2003打开”

\r\n

有人想为Office2010文档在右键菜单里添加Office2003打开方式的选项,以便在工作中偶尔需要将文档用Office2003打开,则需要做如下设置:
先在文件夹选项——文件类型里找到docx,然后选高级—新建
“操作”里填写:“用Word 2003打开”
“用于执行操作的应用程序”里填写:

\r\n
\"C:Program FilesMicrosoft OfficeOffice11WINWORD.EXE\" /n \"%1\"
\r\n

同样 xls 和 ppt 文件 也要做类似设置:在文件夹选项——文件类型里找到xlsx,然后选高级——新建“操作”里填写:“用Excel 2003打开”
“用于执行操作的应用程序”里填写:

\r\n
\"C:Program FilesMicrosoft OfficeOffice11EXCEL.EXE\" /e \"%1\"
\r\n

在文件夹选项——文件类型里找到pptx,然后选高级——新建“操作”里填写:“用PowerPoint2003打开”
“用于执行操作的应用程序”里填写:

\r\n
\"C:Program FilesMicrosoft OfficeOffice11POWERPNT.EXE\" \"%1\"
\r\n

这样右击这三种Office2010文档,右键菜单就有用Office 2003打开的选项了。

\r\n

6、为Office2003文档在右键菜单里添加“用Office2010打开”

\r\n

也有人想为Office2003文档在右键菜单里添加Office2010打开方式的选项,以便在工作中偶尔需要将文档用Office2010打开,则需要做如下设置:

\r\n

先在文件夹选项——文件类型里找到doc,然后选高级—新建。“操作”里填写:用Word 2010打开
“用于执行操作的应用程序”里填写:

\r\n
\"D:Program FilesMicrosoft OfficeOffice14WINWORD.EXE\" /n \"%1\"
\r\n

同样 xls 和 ppt 文件 也要做类似设置:

\r\n

在文件夹选项——文件类型里找到xls,然后选高级—新建。“操作”里填写:用Excel 2010打开
“用于执行操作的应用程序”里填写:

\r\n
\"D:Program FilesMicrosoft OfficeOffice14EXCEL.EXE\" /e \"%1\"
\r\n

在文件夹选项——文件类型里找到ppt,然后选高级—新建。“操作”里填写:用PowerPoint2010打开
“用于执行操作的应用程序”里填写:

\r\n
\"D:Program FilesMicrosoft OfficeOffice14POWERPNT.EXE\" \"%1\"
\r\n

这样右击这三种Office2003文档,右键菜单就有用Office 2010打开的选项了。

\r\n

6、安装了Office 2010之后,鼠标右键新建中,创建的Word只能是.docx格式(Office 2007/2010版本),却没办法直接创建Office 2003版本的新建文件。这里我们执行以上操作后在右键新建菜单里两种版本的新建文件都可以创建了。至此就让office 2003 2010完美共存了。

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2778, 'mysls-output-sls-settings', 'MyXls导出Excel的各种设置', '2013-03-28 19:15:47', '2019-03-25 21:29:22', '

[copy]http://qepdcwqxl.blog.163.com/blog/static/2275121820121116103349700/[/copy]

\r\n

MyXls是一个操作Excel的开源类库,支持设置字体、列宽、行高、合并单元格、边框、背景颜色、数据类型、自动换行、对齐方式等,通过众多项目的使用表现,证明MyXls对于创建简单格式的Excel文件十分快捷方便。

\r\n

本文将通过实例的方式详细说明如何通过各种属性设置MyXls的样式:

\r\n

 

\r\n

            // 准备测试数据

\r\n

            varlist = newList<PersonInfo>();

\r\n

            for (inti = 1; i <= 200; i++)

\r\n

            {

\r\n

                varperson = newPersonInfo

\r\n

                {

\r\n

                    RealName = \"\" + i,

\r\n

                    Gender = (i%2 == 0 ? \"\" : \"\"),

\r\n

                    Age = 20 + (i%3)

\r\n

                };

\r\n

                list.Add(person);

\r\n

            }

\r\n

            intrecordCount = 200; // 要导出的记录总数

\r\n

            intmaxRecordCount = 100; // 每个sheet表的最大记录数

\r\n

            intsheetCount = 1; // Sheet表的数目

\r\n

            varxls = newXlsDocument();

\r\n

            xls.FileName = \"MyXls-\" + DateTime.Now.ToString(\"yyyyMMddHHmmss\") + \".xls\"; // 计算需要多少个sheet表显示数据

\r\n

            if (recordCount > maxRecordCount)

\r\n

            {

\r\n

                sheetCount = (int) Math.Ceiling(recordCount/(decimal) maxRecordCount);

\r\n

            } // Sheet标题样式

\r\n

            XFtitleXF = xls.NewXF(); // xls生成一个XF实例,XF是单元格格式对象

\r\n

            titleXF.HorizontalAlignment = HorizontalAlignments.Centered; // 设定文字居中

\r\n

            titleXF.VerticalAlignment = VerticalAlignments.Centered; // 垂直居中

\r\n

            titleXF.UseBorder = true; // 使用边框

\r\n

            titleXF.TopLineStyle = 1; // 上边框样式

\r\n

            titleXF.TopLineColor = Colors.Black; // 上边框颜色

\r\n

            titleXF.LeftLineStyle = 1; // 左边框样式

\r\n

            titleXF.LeftLineColor = Colors.Black; // 左边框颜色

\r\n

            titleXF.RightLineStyle = 1; // 右边框样式

\r\n

            titleXF.RightLineColor = Colors.Black; // 右边框颜色

\r\n

            titleXF.Font.FontName = \"宋体\"; // 字体

\r\n

            titleXF.Font.Bold = true; // 是否加楚

\r\n

            titleXF.Font.Height = 12*20; // 字大小(字体大小是以 1/20 point 为单位的)// 列标题样式

\r\n

            XFcolumnTitleXF = xls.NewXF(); // xls生成一个XF实例,XF是单元格格式对象

\r\n

            columnTitleXF.HorizontalAlignment = HorizontalAlignments.Centered; // 设定文字居中

\r\n

            columnTitleXF.VerticalAlignment = VerticalAlignments.Centered; // 垂直居中

\r\n

            columnTitleXF.UseBorder = true; // 使用边框

\r\n

            columnTitleXF.TopLineStyle = 1; // 上边框样式

\r\n

            columnTitleXF.TopLineColor = Colors.Black; // 上边框颜色

\r\n

            columnTitleXF.BottomLineStyle = 1; // 下边框样式

\r\n

            columnTitleXF.BottomLineColor = Colors.Black; // 下边框颜色

\r\n

            columnTitleXF.LeftLineStyle = 1; // 左边框样式

\r\n

            columnTitleXF.LeftLineColor = Colors.Black; // 左边框颜色

\r\n

            columnTitleXF.Pattern = 1; // 单元格填充风格。如果设定为0,则是纯色填充(无色)1代表没有间隙的实色

\r\n

            columnTitleXF.PatternBackgroundColor = Colors.Red; // 填充的底色

\r\n

            columnTitleXF.PatternColor = Colors.Default2F; // 填充背景色// 数据单元格样式

\r\n

            XFdataXF = xls.NewXF(); // xls生成一个XF实例,XF是单元格格式对象

\r\n

            dataXF.HorizontalAlignment = HorizontalAlignments.Centered; // 设定文字居中

\r\n

            dataXF.VerticalAlignment = VerticalAlignments.Centered; // 垂直居中

\r\n

            dataXF.UseBorder = true; // 使用边框

\r\n

            dataXF.LeftLineStyle = 1; // 左边框样式

\r\n

            dataXF.LeftLineColor = Colors.Black; // 左边框颜色

\r\n

            dataXF.BottomLineStyle = 1; // 下边框样式

\r\n

            dataXF.BottomLineColor = Colors.Black; // 下边框颜色

\r\n

            dataXF.Font.FontName = \"宋体\";

\r\n

            dataXF.Font.Height = 9*20; // 设定字大小(字体大小是以 1/20 point 为单位的)

\r\n

            dataXF.UseProtection = false; // 默认的就是受保护的,导出后需要启用编辑才可修改

\r\n

            dataXF.TextWrapRight = true;

\r\n

            // 自动换行// 遍历创建Sheetfor (int i = 1; i <=
sheetCount; i++){    //
根据计算出来的Sheet数量,一个个创建    // 行和列的设置需要添加到指定的Sheet中,且每个设置对象不能重用(因为可以设置起始和终止行或列,就没有太大必要重用了,这应是一个策略问题)

\r\n

            Worksheetsheet;

\r\n

            if (sheetCount == 1)

\r\n

            {

\r\n

                sheet = xls.Workbook.Worksheets.Add(\"人员信息表\");

\r\n

            }

\r\n

            else

\r\n

            {

\r\n

                sheet = xls.Workbook.Worksheets.Add(\"人员信息表 - \" + i);

\r\n

            } // 序号列设置

\r\n

            varcol0 = newColumnInfo(xls, sheet); // 列对象  

\r\n

            col0.ColumnIndexStart = 0; // 起始列为第1列,索引从0开始

\r\n

            col0.ColumnIndexEnd = 0; // 终止列为第1列,索引从0开始 

\r\n

            col0.Width = 8*256; // 列的宽度计量单位为 1/256 字符宽

\r\n

            sheet.AddColumnInfo(col0); // 把格式附加到sheet页上    // 姓名列设置

\r\n

            varcol1 = newColumnInfo(xls, sheet); // 列对象

\r\n

            col1.ColumnIndexStart = 1; // 起始列为第2列,索引从0开始

\r\n

            col1.ColumnIndexEnd = 1; // 终止列为第2列,索引从0开始 

\r\n

            col1.Width = 16*256; // 列的宽度计量单位为 1/256 字符宽

\r\n

            sheet.AddColumnInfo(col1); // 把格式附加到sheet页上    // 性别列设置 

\r\n

            varcol2 = newColumnInfo(xls, sheet); // 列对象   

\r\n

            col2.ColumnIndexStart = 2; // 起始列为第3列,索引从0开始 

\r\n

            col2.ColumnIndexEnd = 2; // 终止列为第3列,索引从0开始  

\r\n

            col2.Width = 16*256; // 列的宽度计量单位为 1/256 字符宽

\r\n

            sheet.AddColumnInfo(col2); // 把格式附加到sheet页上    // 年龄列设置

\r\n

            varcol3 = newColumnInfo(xls, sheet); // 列对象  

\r\n

            col3.ColumnIndexStart = 3; // 起始列为第4列,索引从0开始 

\r\n

            col3.ColumnIndexEnd = 3; // 终止列为第4列,索引从0开始 

\r\n

            col3.Width = 16*256; // 列的宽度计量单位为 1/256 字符宽

\r\n

            sheet.AddColumnInfo(col3); // 把格式附加到sheet页上    // 行设置  

\r\n

            varrol1 = newRowInfo(); // 行对象

\r\n

            rol1.RowHeight = 16*20; // 行高 

\r\n

            rol1.RowIndexStart = 3; // 行设置起始列,索引从1开始 

\r\n

            rol1.RowIndexEnd = (ushort) (maxRecordCount + 2); //行设置结束列

\r\n

            sheet.AddRowInfo(rol1); // 把设置附加到sheet页上    // 合并单元格    //

\r\n

            sheet.Cells.Merge(1, 1, 1, 4);

\r\n

            vartitleArea = newMergeArea(1, 1, 1, 4); // 一个合并单元格实例(合并第1行、第11行、第4)   

\r\n

            sheet.AddMergeArea(titleArea); //填加合并单元格     // 开始填充数据到单元格 

\r\n

            Cellscells = sheet.Cells; // Sheet标题行,行和列的索引都是从1开始的

\r\n

            Cellcell = cells.Add(1, 1, \"人员信息统计表\", titleXF);

\r\n

            cells.Add(1, 2, \"\", titleXF); // 合并单元格后仍需要设置每一个单元格,样式才有效 

\r\n

            cells.Add(1, 3, \"\", titleXF); // 合并单元格后仍需要设置每一个单元格,样式才有效

\r\n

            cells.Add(1, 4, \"\", titleXF); // 合并单元格后仍需要设置每一个单元格,样式才有效 

\r\n

            sheet.Rows[1].RowHeight = 40*20; // 对指定的行设置行高    // 列标题行 

\r\n

            cells.Add(2, 1, \"序号\", columnTitleXF);

\r\n

            cells.Add(2, 2, \"姓名\", columnTitleXF);

\r\n

            cells.Add(2, 3, \"性别\", columnTitleXF); // 最右侧的列需要右边框,通过修改样式columnTitleXF的方式,还可以通过设置单元格属性的方式实现。

\r\n

            columnTitleXF.RightLineStyle = 1;

\r\n

            columnTitleXF.RightLineColor = Colors.Black;

\r\n

            cells.Add(2, 4, \"年龄\", columnTitleXF);

\r\n

            sheet.Rows[2].RowHeight = 18*20; // 对指定的行设置行高    // 行索引

\r\n

            introwIndex = 3;

\r\n

            for (intj = 0; j < maxRecordCount; j++)

\r\n

            {

\r\n

                // 当前记录在数据集合中的索引   

\r\n

                intk = (i - 1)*maxRecordCount + j; // 如果达到sheet最大记录数则跳出

\r\n

                if (k >= recordCount)

\r\n

                {

\r\n

                    break;

\r\n

                } // 设置单元格的值     

\r\n

                cells.Add(rowIndex, 1, k + 1, dataXF);

\r\n

                cells.Add(rowIndex, 2, list[k].RealName, dataXF);

\r\n

                cells.Add(rowIndex, 3, list[k].Gender, dataXF);

\r\n

                // 最右侧的列需要右边框,通过给Cell设置属性的方式实现,因为并不是所有的单元格都需要设置,不能通过修改样式dataXF的方式    

\r\n

                CelllastCell = cells.Add(rowIndex, 4, list[k].Age, dataXF);

\r\n

                lastCell.RightLineStyle = 1;

\r\n

                lastCell.RightLineColor = Colors.Black; // 行号递增   

\r\n

                rowIndex++;

\r\n

            }

\r\n

        }

\r\n

        // 在浏览器中输出Excel文件xls.Send();

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2779, 'asp-net-dynamic-reference-webservice', 'asp.net动态引用WebService', '2013-03-22 22:31:21', '2019-03-25 21:29:22', '
\r\n

\r\n     有经验的朋友都知道,通常我们在引用webservice的时候,是在项目中就添加了引用,但是如果一但这个webservice有变动,怎么办?重新打开项目重新引用,重新编译?这是不是太麻烦了,如果对方升级频繁,那我要改项目要改死。怎么解决这样的问题呢?
\r\n 今天我们就来讲一下动态的引用webservice

\r\n

\r\n
\r\n     为此我们需要在web.config中动态配置WebService的地址

\r\n

\r\n 首先手动的添加一个Web引用(这个就不用说了吧)

\r\n

\r\n 然后修改本地的代理类(添加一个新类,继承你的 WebService代理类)
\r\n  

\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\nnamespace Web_Service\r\n{\r\n[System.Diagnostics.DebuggerStepThrough(),System.ComponentModel.DesignerCategory("code"),\r\nSystem.Web.Services.WebServiceBinding(Name = "", Namespace = "")]\r\npublic class DynWebService : SelfWebService\r\n{\r\npublic DynWebService() : base()\r\n{\r\n\r\n//设置默认webService的地址\r\nthis.Url = "http://localhost/WebService.asmx";\r\n}\r\npublic DynWebService(string webUrl) : base()\r\n{\r\nthis.Url = webUrl;\r\n}\r\n}\r\n}\r\n
\r\n
\r\n
\r\n\r\n

\r\n     说明:SelfWebService 你引用的 WebService。Web Service的URI部署到配置文件里

\r\n

\r\n <add key="WebServiceKey"value="http://www.mhzg.net/WebService.asmx"/>

\r\n

\r\n     最后实现

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\nprivate void WebServiceTest()\r\n{\r\nstring webServiceUrl = ConfigurationManager.AppSettings["WebServiceKey "].ToString();\r\nWeb_Service.DynWebService dws = new Web_Service.DynWebService(webServiceUrl);\r\nstring result = dws.HelloWorld();\r\n}\r\n
\r\n
\r\n\r\n

\r\n  

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2780, 'win7-ime-shortcut-keys-toggle-settings', 'Win7输入法快捷键切换设置', '2013-02-16 13:25:10', '2019-03-25 21:29:22', 'win7系统具体设置步骤:
\r\n      右击输入法图标,点“设置”,再点“高级键设置”,选择“在输入语言之间”,再点“更改按键顺序”,
\r\n注意:
\r\n      这时就是XP和WIN7的差别了。在WIN7这里有二项,一个是切换输入法,一个是切换键盘布局,大家按常理都会把切换输入法那设置成ctrl+Shift,但结果是这样是错的。实际上WIN7是在“切换键盘布局”那一栏选“ctrl+Shift",其它默认即可。这就是WIN7和XP的不同。我就范过这样的错误,所以以后的朋友不要在错了。
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2781, 'jndi%e8%af%a6%e8%a7%a3', 'JNDI详解', '2013-02-01 14:45:50', '2019-03-25 21:29:22', '

\r\n JNDI 是 Java 命名与目录接口(Java Naming and Directory Interface),在 J2EE 规范中是重要的规范之一,不少专家认为,没有透彻理解 JNDI 的意义和作用,就没有真正掌握 J2EE 特别是 EJB 的知识。
\r\n 那么,JNDI 到底起什么作用?

\r\n

\r\n 要了解 JNDI 的作用,我们可以从两个方面来探讨:

\r\n

\r\n 1. 如果不用 JNDI 我们怎样做?

\r\n

\r\n 程序员开发时,知道要开发访问 MySQL 数据库的应用,于是将一个对 MySQL JDBC 驱动程序类的引用进行了编码,并通过使用适当的 JDBC URL 连接到数据库。就像以下代码这样:

\r\n
\r\n

\r\n Connection conn=null;
\r\n try {
\r\n Class.forName(“com.mysql.jdbc.Driver”,
\r\n true, Thread.currentThread().getContextClassLoader());
\r\n conn=DriverManager.getConnection(“jdbc:mysql://MyDBServer?user=qingfeng&password=mingyue”);
\r\n /* 使用 conn 并进行 SQL 操作 */
\r\n ……
\r\n conn.close();
\r\n }
\r\n catch(Exception e) {
\r\n e.printStackTrace();
\r\n }
\r\n finally {
\r\n if(conn!=null) {
\r\n try {
\r\n conn.close();
\r\n } catch(SQLException e) {}
\r\n }
\r\n }

\r\n
\r\n

\r\n 这是传统的做法,也是以前非 Java 程序员(如 Delphi、VB 等)常见的做法。这种做法一般在小规模的开发过程中不会产生问题,只要程序员熟悉 Java 语言、了解 JDBC 技术和 MySQL,可以很快开发出相应的应用程序。

\r\n

\r\n 但是这种传统的方法存在很多问题:

\r\n
    \r\n
  1. \r\n 数据库服务器名称 MyDBServer 、用户名和口令都可能需要改变,由此引发 JDBC URL 需要修改;
  2. \r\n
  3. \r\n 数据库可能改用别的产品,如改用 DB2 或者 Oracle,引发 JDBC 驱动程序包和类名需要修改;
  4. \r\n
  5. \r\n 随着实际使用终端的增加,原配置的连接池参数可能需要调整;
  6. \r\n
  7. \r\n ……
  8. \r\n
\r\n

\r\n 解决办法:
\r\n 程序员应该不需要关心“具体的数据库后台是什么?JDBC 驱动程序是什么?JDBC URL格式是什么?访问数据库的用户名和口令是什么?”等等这些问题,程序员编写的程序应该没有对 JDBC 驱动程序的引用,没有服务器名称,没有用户名称或口令 —— 甚至没有数据库池或连接管理。而是把这些问题交给 J2EE 容器来配置和管理,程序员只需要对这些配置和管理进行引用即可。

\r\n

\r\n 由此,就有了 JNDI。

\r\n

\r\n 2. 用了 JNDI 后我们又将怎样做?

\r\n

\r\n 首先,在在 J2EE 容器中配置 JNDI 参数,定义一个数据源,也就是 JDBC 引用参数,给这个数据源设置一个名称;然后,在程序中,通过数据源名称引用数据源从而访问后台数据库。
\r\n 具体操作如下(以 JBoss 为例):

\r\n

\r\n 1. 配置数据源
\r\n 将其中的 mysql-ds.xml 文件Copy到你使用的服务器 deploy 目录下,修改 mysql-ds.xml 文件的内容,使之能通过 JDBC 正确访问你的 MySQL 数据库,代码如下:

\r\n
\r\n

\r\n <?xml version=”1.0″ encoding=”UTF-8″?>
\r\n < datasources>
\r\n < local-tx-datasource>
\r\n < jndi-name>MySqlDS</jndi-name>
\r\n < connection-url>jdbc:mysql://localhost:3306/lw</connection-url>
\r\n < driver-class>com.mysql.jdbc.Driver</driver-class>
\r\n <user-name>root</user-name>
\r\n < password>rootpassword</password>
\r\n < exception-sorter-class-name>
\r\n org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter
\r\n < /exception-sorter-class-name>
\r\n < metadata>
\r\n < type-mapping>mySQL</type-mapping>
\r\n < /metadata>
\r\n < /local-tx-datasource>
\r\n < /datasources>

\r\n
\r\n

\r\n 这里,定义了一个名为 MySqlDS 的数据源,其参数包括 JDBC 的 URL,驱动类名,用户名及密码等。

\r\n

\r\n 2. 在程序中引用数据源:

\r\n
\r\n

\r\n Connection conn=null;
\r\n try {
\r\n Context ctx=new InitialContext();
\r\n Object datasourceRef=ctx.lookup(“java:MySqlDS“); //引用数据源
\r\n DataSource ds=(Datasource)datasourceRef;
\r\n conn=ds.getConnection();
\r\n /* 使用conn进行数据库SQL操作 */
\r\n ……
\r\n c.close();
\r\n }
\r\n catch(Exception e) {
\r\n e.printStackTrace();
\r\n }
\r\n finally {
\r\n if(conn!=null) {
\r\n try {
\r\n conn.close();
\r\n } catch(SQLException e) { }
\r\n }
\r\n }

\r\n
\r\n

\r\n 直接使用 JDBC 或者通过 JNDI 引用数据源的编程代码量相差无几,但是现在的程序可以不用关心具体 JDBC 参数了。
\r\n 在系统部署后,如果数据库的相关参数变更,只需要重新配置 mysql-ds.xml 修改其中的 JDBC 参数,只要保证数据源的名称不变,那么程序源代码就无需修改。

\r\n

\r\n 由此可见,JNDI 避免了程序与数据库之间的紧耦合,使应用更加易于配置、易于部署。

\r\n

\r\n 3. JNDI 的架构

\r\n

\r\n JNDI 架构提供了一个标准的、与命名系统无关的 API,这个 API 构建在特定于命名系统的驱动程序之上。这一层帮助把应用程序和实际的数据源隔离开来,因此无论应用程序是访问 LDAP、RMI、DNS 还是其他的目录服务,这都没有关系。换句话说,JNDI 与任何特定的目录服务实现无关,您可以使用任何目录,只要您拥有相应的服务提供程序接口(或驱动程序)即可,如下图所示:

\r\n

\r\n \"JNDI_architecture\"

\r\n

\r\n 注意,关于 JNDI 有一点很重要,即它同时提供应用程序编程接口(Application Programming Interface ,API)和服务提供程序接口(Service Provider Interface ,SPI)。这样做的实际意义在于,对于您的与命名或目录服务交互的应用程序来说,必须存在用于该服务的一个 JNDI 服务提供程序,这便是 JNDI SPI 发挥作用的舞台。一个服务提供程序基本上就是一组类,这些类针对特定的命名和目录服务实现了各种 JNDI 接口——这与 JDBC 驱动程序针对特定的数据系统实现各种 JDBC 接口极为相似。作为一名应用程序开发人员,您不需要担心 JNDI SPI。您只需确保,您为每个想使用的命名或目录服务提供了一个服务提供程序。

\r\n

\r\n 4. JNDI 的扩展

\r\n

\r\n JNDI 在满足了数据源配置的要求的基础上,还进一步扩充了作用:所有与系统外部的资源的引用,都可以通过 JNDI 定义和引用。

\r\n

\r\n 所以,在 J2EE 规范中,J2EE 中的资源并不局限于 JDBC 数据源。引用的类型有很多,其中包括资源引用(已经讨论过)、环境实体和 EJB 引用。特别是 EJB 引用,它暴露了 JNDI 在 J2EE 中的另外一项关键角色:查找其他应用程序组件。

\r\n

\r\n EJB 的 JNDI 引用非常类似于 JDBC 资源的引用。在服务趋于转换的环境中,这是一种很有效的方法。可以对应用程序架构中所得到的所有组件进行这类配置管理,从 EJB 组件到 JMS 队列和主题,再到简单配置字符串或其他对象,这可以降低随时间的推移服务变更所产生的维护成本,同时还可以简化部署,减少集成工作。 外部资源。

\r\n

\r\n 5. 总结

\r\n

\r\n J2EE 规范要求所有 J2EE 容器都要提供 JNDI 规范的实现。JNDI 在 J2EE 中的角色就是“交换机” —— J2EE 组件在运行时间接地查找其他组件、资源或服务的通用机制。在多数情况下,提供 JNDI 供应者的容器可以充当有限的数据存储,这样管理员就可以设置应用程序的执行属性,并让其他应用程序引用这些属性(Java 管理扩展(Java Management Extensions,JMX)也可以用作这个目的)。JNDI  在 J2EE 应用程序中的主要角色就是提供间接层,这样组件就可以发现所需要的资源,而不用了解这些间接性。

\r\n

\r\n 在 J2EE 中,JNDI 是把 J2EE 应用程序合在一起的粘合剂,JNDI 提供的间接寻址允许跨企业交付可伸缩的、功能强大且很灵活的应用程序。这是 J2EE 的承诺,而且经过一些计划和预先考虑,这个承诺是完全可以实现的。

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2782, 'installation-and-configuration-of-subversion', 'Svn学习笔记001:Subversion的安装与配置', '2012-12-23 13:51:03', '2019-03-25 21:29:22', '       如何快速建立Subversion服务器,并且在项目中使用起来,这是大家最关心的问题,与CVS相比,Subversion有更多的选择,也更加的容易,几个命令就可以建立一套服务器环境,可以使用起来。 \r\n\r\n      首先,先介绍几个基本概念.这些概念CVS里面也有.但是咋学的是CVS的更新版本~!~.\r\n\r\nRepository 仓库,就是存放工程的地方.(SubVersion就是让你的工程有版本控制).这里注意一下,仓库里面可以有多个工程..彼此互不关联.\r\n\r\nModule  可以叫模块,其实就是仓库里的一个工程.对应服务器根目录下面的第一级子目录...\r\n\r\nImport  导入,很容易理解,就是将需要管理的工程放入仓库\r\n\r\nCheckout 导出,对面上面的导入\r\n\r\nCommit  提交修改..当你修改工程下的一个文件以后就需要提交修改\r\n\r\nUpdate 更新.就是将服务器中的最新版本下载下来.\r\n\r\nRevision 文件版本..注意,这里是单个文件的版本,不是整个工程的版本\r\n\r\n \r\n\r\nRelease 发行版本.这个才是整个文件的版本.\r\n\r\nTag 标签.\r\n\r\n下面开始配置:\r\n

1、软件下载

\r\n

下载Subversion服务器程序。

\r\n到官方网站的下载二进制安装文件,来到二进制包下载部分,找到 Windows NT, 2000, XP and 2003部分,然后选择Apache 2.0 或者 Apache 2.2,这样我们可以看到许多下载的内容,目前可以下载Setup-Subversion-1.5.3.msi 。\r\n

下载Subversion的Windows客户端TortoiseSVN。

\r\nTortoiseSVN是扩展Windows Shell的一套工具,可以看作Windows资源管理器的插件,安装之后Windows就可以识别Subversion的工作目录。\r\n官方网站是TortoiseSVN ,下载方式和前面的svn服务器类似,在Download页面的我们可以选择下载的版本,目前的最高稳定版本的安装文件为TortoiseSVN-1.5.5.14361-win32-svn-1.5.4.msi。\r\n

2、服务器和客户端安装

\r\n服务器安装,直接运行Setup-Subversion-1.5.3.msi ,根据提示安装即可,这样我们就有了一套服务器可以运行的环境。\r\n\r\n安装TortoiseSVN,同样直接运行TortoiseSVN-1.5.5.14361-win32-svn-1.5.4.msi按照提示安装即可,不过最后完成后会提示是否重启,其实重启只是使svn工作拷贝在windows中的特殊样式生效,与所有的实际功能无关,这里为了立刻看到好的效果,还是重新启动机器。\r\n

3,建立版本库(Repository)

\r\n首先在D盘建立一个空文件夹SvnWorkplace\r\n\"\"\r\n\r\n运行Subversion服务器需要首先要建立一个版本库(Repository),可以看作服务器上存放数据的数据库,在安装了Subversion服务器之后,可以直接运行,如:\r\n
svnadmin create D:SvnWorkplacerepository
\r\n就会在目录D:SvnWorkplacerepository下创建一个版本库。\r\n\r\n\"\"\r\n\r\n\"\"\r\n\r\n\"\"\r\n\r\n我们也可以使用TortoiseSVN图形化的完成这一步(这里就不在演示了):\r\n在目录E:svndemorepository下\"右键->TortoiseSVN->Create Repository here...“, 然后可以选择版本库模式, 这里使用默认即可, 然后就创建了一系列目录和文件。\r\n\r\n4、配置用户和权限\r\n\r\n \r\n

5、导入

\r\n \r\n\r\n(1)当然,首先需要启动服务器。输入命令\r\n\r\nsvnserve –d –r D:SvnWorkplacerepository\r\n\r\n\"\"\r\n\r\n      该命令含义为让SVN将此目录作为仓库,并侦听客户端的请求。其中-d的作用为后台模式,而-r的作用为指定服务器的仓库路径。\r\n\r\n      注意,当服务器启动后,请不要关闭该命令行窗口,否则也会把svnserve服务停下来,接下来的操作我们可以另外打开一个命令行窗口进行。\r\n\r\n(2)假设我们的客户端创建的项目在E:svnclient,我们在该目录下创建一个文件夹child和一个文件Readme.txt,并在该文件中增加一些文本。\r\n\r\n\"\"\r\n\r\n(3)在系统环境变量中增加一个SVN_EDITOR 他的值我们使用notepad(即是记事本).这个是写入日志用的。这里也可以指定一个日志文件。下面我们会使用日志文件.因为用添加SVN_EDITOR的办法每次运行都要跳出一个日志文件。注意,修改了环境变量以后需要关闭cmd页面,重新打开才有效。\r\n\r\n\"\"\r\n\r\n(4)打开另外一个cmd文件,进入我们的工程目录.我们这里是 E:svn  运行\r\n\r\nsvn import svn://localhost\r\n\r\n接下俩会跳出一个记事本,是输入日志用的.点关闭.\r\n\r\n      输入c ,回车,接下来按要求输入用户名和密码。我们可以看到import成功了.如图\r\n\r\n\"\"\r\n\r\n(5)接下来,我们再创建一个目录.位置为E:svnclient2,再里面创建一个文件夹child2和一个文本文件Readme2.txt,在test2中输入一些文本。\r\n\r\n5 打开命令行,输入 svn mkdir svn://localhost/project2 然后关闭记事本,继续.如图\r\n\r\n\"SubVersion学习笔记1\r\n\r\n .该命令的作用是在服务器端创建一个虚拟目录project2.今后我们的项目可以import到该目录下\r\n\r\n6 将test2工程放入虚拟目录\r\n\r\n将命令行对位到e:test2\r\n\r\n\"SubVersion学习笔记1\r\n\r\n \r\n\r\n上面的操作就是Import操作了\r\n

\r\n  ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2783, 'using-intellij-idea-build-apache-myfaces-step-by-step', '用IntelliJ IDEA构建Apache MyFaces-循序渐进', '2012-12-23 09:35:06', '2019-03-25 21:29:22', '

\r\n 用IntelliJ IDEA构建Apache MyFaces-循序渐进
\r\n
\r\n 准备maven和maven-idea-plugin

\r\n
\r\n 下载和安装maven
\r\n 1.在http://maven.apache.org/ 下载最新的maven版本
\r\n 2.按照http://maven.apache.org 的安装指南安装maven
\r\n
\r\n 准备最新的maven-idea-plugin

\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n 原文:http://wiki.apache.org/myfaces/JetBrains_IntelliJ_IDEA
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n  

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2784, 'the-xp-system-when-you-visit-certain-websites-fonts-fuzzy-method', '解决xp系统浏览某些网页时,字体模糊的方法', '2012-12-22 22:25:10', '2019-03-25 21:29:22', '      Win7用了一段时间,非常不错,但是就是用的时间长了以后就会卡,哎··· 我天天用360清理垃圾,但是还是这样,纠结了,又换了xp的,好吧就这样,先着用着,以后再换系统的时候在用win7 (*^__^*) 嘻嘻……用win7习惯了,用xp赶紧很不习惯哦···\r\n

\r\n        网上也有很多问xp和win7那个好用的问题的,其实吧个人感觉适合你就行,各有各的有点各有各的缺点,依据个人爱好慢慢选择,慢慢体会吧···

\r\n

\r\n        现在流行微软雅黑,但是xp的系统登录这些网站时候文字就会显示的模糊不行,解决方法我截了图,网上也有很多;

\r\n

\r\n        解决xp系统浏览某些网页时,字体模糊的方法:

\r\n

\r\n       桌面---右键---属性---外观---效果---清晰,ok了!
\r\n \"\"

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2785, 'manually-add-the-maven-jar-package-to-a-local-warehouse', 'Maven学习笔记002:Maven 手动添加 JAR 包到本地仓库', '2012-12-21 06:13:50', '2019-03-25 21:29:22', '
\r\nMaven 确确实实是个好东西,用来管理项目显得很方便,但是如果是通过 Maven 来远程下载 JAR 包的话,我宿舍的带宽是4兆的,\r\n4个人共用,有时候用 Maven 来远程下载 JAR 包会显得很慢,一般我发现下载速度不明显的时候,我就 Ctrl + C 来终止它的下载。\r\n然后改用手动来下载,因为用迅雷一类的工具来下载会快很多。我机子上 Maven 的本地仓库的很多 JAR 包我都是手动下载的。\r\n手动下载的话就会带来一个问题,就是,怎么样手动将下载下来的 JAR 包添加到 Maven 的本地仓库。关于这个,网上也有很多资料。\r\n我说下我的做法。\r\n首先,\r\n推荐几个好的 Maven 常用仓库网址:\r\nhttp://mvnrepository.com/\r\nhttp://search.maven.org/\r\nhttp://repository.sonatype.org/content/groups/public/\r\nhttp://people.apache.org/repo/m2-snapshot-repository/\r\nhttp://people.apache.org/repo/m2-incubating-repository/\r\n\r\n第一个是我最常用的,然后是第二个,然后是第三个,最后两个是 Apache 的私有仓库,我还没用过,不过感觉应该还可以吧...\r\n接下来,还是一贯的作风,使用截图通俗易懂的方式来解说:\r\n\r\n如果你看过我的上一篇:Spring邮件服务之Html:Maven + Spring SMTP Mail With Html 文章,里面需要用到一个\r\nspring-context-support-3.1.0.RELEASE.jar 的 JAR 包,我把它安装到本地仓库的时候把图截了下来,顺便写了这篇文章,\r\n供有需要的网友参考。\r\n首先,到 http://mvnrepository.com/ 这个网,在搜索栏中输入你要搜索的 JAR 包的关键字来搜索,下面直接贴图:\r\n\r\n@1图\r\n\"\"\r\n\r\n@2图\r\n\"\"\r\n\r\n@3图\r\n\"\"\r\n\r\n以 spring-context-support-3.1.0.RELEASE.jar 为例,在 @3图中已经给出这个 jar 包的 groupId,artifactId,version信息,\r\n手动安装的时候这些信息不要改,否则 Maven 项目移植的话,jar 包下载就会失败。顺便把这信息帖下面,方便对照:\r\n

\"\"<dependency>\r\n\"\"    <groupId>org.springframework</groupId>\r\n\"\"    <artifactId>spring-context-support</artifactId>\r\n\"\"    <version>3.1.0.RELEASE</version>\r\n\"\"</dependency>

\r\n\r\nMaven 安装 JAR 包的命令是:\r\n

\"\"mvn install:install-file -Dfile=jar包的位置 -DgroupId=上面的groupId -DartifactId=上面的artifactId -Dversion=上面的version -Dpackaging=jar

\r\n\r\n例如:\r\n我下载的这个 jar 包是放到了 D:mvn 目录下(D:mvnspring-context-support-3.1.0.RELEASE.jar)\r\n那么我在 cmd 中敲入的命令就应该是:\r\n\r\nmvn install:install-file -Dfile=D:mvnspring-context-support-3.1.0.RELEASE.jar -DgroupId=org.springframework -DartifactId=spring-context-support -Dversion=3.1.0.RELEASE -Dpackaging=jar\r\n\r\n回车,显示安装成功:\r\n\r\n\"\"\r\n\r\n
\r\n文章转载自:http://www.blogjava.net/fancydeepin ]\r\n\r\n ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2786, 'maven-combat-a-installation-and-configuration', 'Maven学习笔记001:Maven实战(一)安装和配置', '2012-12-21 05:54:50', '2019-03-25 21:29:22', ' 1. 简介 \r\n\r\nMaven是基于项目对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的软件项目管理工具.\r\n如果你已经有十次输入同样的Ant targets来编译你的代码、jar或者war、生成javadocs,你一定会自问,是否有一个重复性更少却能同样完成该工作的方 法。 Maven便提供了这样一种选择,将你的注意力从作业层转移到项目管理层。Maven项目已经能够知道如何构建和捆绑代码,运行测试,生成文档并宿主项目 网页\r\n\r\n2.核心价值\r\n\r\n* 简单\r\nMaven 暴露了一组一致、简介的操作接口,能帮助团队成员从原来的高度自定义的、复杂的构建系统中解脱出来,使用Maven现有的成熟的、稳定的组件也能简   化构建系统的复杂度。\r\n\r\n* 交流与反馈\r\n与版本控制系统结合后,多有人都能执行最新的构建并快速得到反馈。此外,自动生成的项目报告也能帮助成员了解项目的状态,促进团队的交流。\r\n\r\n* 测试驱动开发\r\n      TDD强调测试先行,所有产品都应该由测试用例覆盖。而测试是maven生命周期的最重要组成部分之一,并且Maven有现成的成熟插件支持业界流行的测试框架,如Junit和TestNG。\r\n\r\n* 快速构建\r\n只需要一些配置,之后用一条简单的命令就能让Maven帮你清理、编译、测试、打包、部署,然后得到最终产品。[/size]\r\n\r\n* 持续集成\r\n      更加方便的持续集成\r\n\r\n* 富有信息的工作区\r\n\r\n2.主要内容\r\n\r\n我将会发表一系列课程来讲解Maven的应用,基于Maven3.0,主要内容如下:\r\n\r\n1)安装和配置\r\n\r\n2)Maven使用入门\r\n\r\n3)坐标和依赖\r\n\r\n4)Maven仓库\r\n\r\n5)  生命周期和插件\r\n\r\n6)聚合与继承\r\n\r\n7)使用Nexus创建私服\r\n\r\n8)使用Maven进行测试\r\n\r\n9)m2eclipse的使用\r\n\r\n10)自动部署maven项目\r\n\r\n11)使用Hudson进行持续集成\r\n\r\n3. 安装好JDK \r\n\r\n以JDK1.5以上为例\r\n\r\n4. Maven 的下载\r\n下载地址:http://maven.apache.org/download.html\r\n\r\n5.Maven安装\r\n\r\n将下载到的文件解压到指定目录即可,如:C:mavenapache-maven-3.0.4\r\n\r\n6.环境变量的配置\r\n\r\n在系统环境变量中新增如下环境变量\r\nM2_HOME:  Maven的安装目录,如:C:mavenapache-maven-3.0.4\r\nM2:  %M2_HOME%bin\r\n并在path中添加%M2%,这样便可以在任何路径中执行mvn命令\r\n\r\n7. 检测安装是否成功 \r\n\r\nCmd窗口执行命令:mvn –v\r\n得到如下图所示结果:\r\n\"\"\r\n 8.设置代理\r\n\r\n  有时候你所在的公司基于安全因素考虑,要求你使用通过安全认证的代理访问因特网。这时就需要为Maven配置HTTP代理。\r\n\r\n   在目录~/.m2/setting.xml文件中编辑如下(如果没有该文件,则复制$M2_HOME/conf/setting.xml),XML代码如下:\r\n
\r\n\r\n
<proxies>\r\n<proxy>\r\n<id>optional</id>\r\n<active>true</active>\r\n<protocol>http</protocol>\r\n<username>proxyuser</username>\r\n<password>proxypass</password>\r\n<host>proxy.host.net</host>\r\n<port>80</port>\r\n<nonProxyHosts>local.net|some.host.com</nonProxyHosts>\r\n</proxy>\r\n</proxies>
\r\n
\r\n ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2787, 'maven-project-structure', 'Maven学习笔记003:maven项目的标准目录结构', '2013-11-13 14:00:00', '2019-03-25 21:29:22', '【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】\r\n\r\n每一个maven工程,它们的目录结构都基本相同,这种目录结构称作maven的标准目录结构,是优秀工程师从大量实践得出来的,结构非常合理。 如果完全遵循标准目录结构,开发人员能够快速的熟悉该工程。\r\n约定优于配置是maven的一个最重要设计理念。\r\n

标准目录结构

\r\nsrc \r\n\r\n  -main \r\n\r\n      –bin 脚本库 \r\n\r\n      –java java源代码文件 \r\n\r\n     –resources 资源库,会自动复制到classes目录里\r\n\r\n      –filters 资源过滤文件 \r\n\r\n      –assembly 组件的描述配置(如何打包)\r\n\r\n      –config 配置文件\r\n\r\n      –webapp web应用的目录。WEB-INFcssjs\r\n\r\n  -test \r\n\r\n      –java 单元测试java源代码文件 \r\n\r\n      –resources 测试需要用的资源库\r\n\r\n      –filters 测试资源过滤库 \r\n\r\n  -site Site(一些文档) \r\n\r\ntarget \r\n\r\nLICENSE.txt 项目版权信息 \r\n\r\nREADME.txt项目说明 \r\n\r\n工程根目录下就只有srctarget两个目录\r\n\r\ntarget是有存放项目构建后的文件和目录,jar包、war包、编译的class文件等。\r\n\r\ntarget里的所有内容都是maven构建的时候生成的 \r\n\r\n附:IntelliJ IDEA的Meven项目架构:\r\n\r\n\"2013-11-11_014925\"\r\n

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2789, 'java-synchronized-xiangjie', 'java synchronized详解', '2012-12-18 23:46:45', '2019-03-25 21:29:22', '

\r\n     Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码

\r\n

\r\n      一、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。

\r\n

\r\n      二、然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。

\r\n

\r\n      三、尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。

\r\n

\r\n      四、第三个例子同样适用其它同步代码块。也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞

\r\n

\r\n      五、以上规则对其它对象锁同样适用.

\r\n

\r\n 举例说明: 
\r\n      一、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。

\r\n

\r\n package ths;

\r\n

\r\n public class Thread1 implements Runnable { 
\r\n      public void run() { 
\r\n           synchronized(this) { 
\r\n                for (int i = 0; i < 5; i++) { 
\r\n                     System.out.println(Thread.currentThread().getName() + " synchronized loop " + i); 
\r\n                } 
\r\n           } 
\r\n      } 
\r\n      public static void main(String[] args) { 
\r\n           Thread1 t1 = new Thread1(); 
\r\n           Thread ta = new Thread(t1, "A"); 
\r\n           Thread tb = new Thread(t1, "B"); 
\r\n           ta.start(); 
\r\n           tb.start(); 
\r\n      }
\r\n }

\r\n

\r\n 结果: 
\r\n      A synchronized loop 0 
\r\n      A synchronized loop 1 
\r\n      A synchronized loop 2 
\r\n      A synchronized loop 3 
\r\n      A synchronized loop 4 
\r\n      B synchronized loop 0 
\r\n      B synchronized loop 1 
\r\n      B synchronized loop 2 
\r\n      B synchronized loop 3 
\r\n      B synchronized loop 4

\r\n

\r\n      二、然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。

\r\n

\r\n package ths;

\r\n

\r\n public class Thread2 { 
\r\n      public void m4t1() { 
\r\n           synchronized(this) { 
\r\n                int i = 5; 
\r\n                while( i-- > 0) { 
\r\n                     System.out.println(Thread.currentThread().getName() + " : " + i); 
\r\n                     try { 
\r\n                          Thread.sleep(500); 
\r\n                     } catch (InterruptedException ie) { 
\r\n                     } 
\r\n                } 
\r\n           } 
\r\n      } 
\r\n      public void m4t2() { 
\r\n           int i = 5; 
\r\n           while( i-- > 0) { 
\r\n                System.out.println(Thread.currentThread().getName() + " : " + i); 
\r\n                try { 
\r\n                     Thread.sleep(500); 
\r\n                } catch (InterruptedException ie) { 
\r\n                } 
\r\n           } 
\r\n      } 
\r\n      public static void main(String[] args) { 
\r\n           final Thread2 myt2 = new Thread2(); 
\r\n           Thread t1 = new Thread(  new Runnable() {  public void run() {  myt2.m4t1();  }  }, "t1"  ); 
\r\n           Thread t2 = new Thread(  new Runnable() {  public void run() { myt2.m4t2();   }  }, "t2"  ); 
\r\n           t1.start(); 
\r\n           t2.start(); 
\r\n      }
\r\n }

\r\n

\r\n 结果: 
\r\n      t1 : 4 
\r\n      t2 : 4 
\r\n      t1 : 3 
\r\n      t2 : 3 
\r\n      t1 : 2 
\r\n      t2 : 2 
\r\n      t1 : 1 
\r\n      t2 : 1 
\r\n      t1 : 0 
\r\n      t2 : 0

\r\n

\r\n      三、尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。

\r\n

\r\n      //修改Thread2.m4t2()方法: 
\r\n      public void m4t2() { 
\r\n           synchronized(this) { 
\r\n                int i = 5; 
\r\n                while( i-- > 0) { 
\r\n                     System.out.println(Thread.currentThread().getName() + " : " + i); 
\r\n                     try { 
\r\n                          Thread.sleep(500); 
\r\n                     } catch (InterruptedException ie) { 
\r\n                     } 
\r\n                } 
\r\n           }

\r\n

\r\n      }

\r\n

\r\n 结果:

\r\n

\r\n      t1 : 4 
\r\n      t1 : 3 
\r\n      t1 : 2 
\r\n      t1 : 1 
\r\n      t1 : 0 
\r\n      t2 : 4 
\r\n      t2 : 3 
\r\n      t2 : 2 
\r\n      t2 : 1 
\r\n      t2 : 0

\r\n

\r\n      四、第三个例子同样适用其它同步代码块。也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。

\r\n

\r\n      //修改Thread2.m4t2()方法如下:

\r\n

\r\n      public synchronized void m4t2() { 
\r\n           int i = 5; 
\r\n           while( i-- > 0) { 
\r\n                System.out.println(Thread.currentThread().getName() + " : " + i); 
\r\n                try { 
\r\n                     Thread.sleep(500); 
\r\n                } catch (InterruptedException ie) { 
\r\n                } 
\r\n           } 
\r\n      }

\r\n

\r\n 结果: 
\r\n      t1 : 4 
\r\n      t1 : 3 
\r\n      t1 : 2 
\r\n      t1 : 1 
\r\n      t1 : 0 
\r\n      t2 : 4 
\r\n      t2 : 3 
\r\n      t2 : 2 
\r\n      t2 : 1 
\r\n      t2 : 0

\r\n

\r\n      五、以上规则对其它对象锁同样适用:

\r\n

\r\n package ths;

\r\n

\r\n public class Thread3 {
\r\n      class Inner {
\r\n           private void m4t1() {
\r\n                int i = 5;
\r\n                while(i-- > 0) {
\r\n                     System.out.println(Thread.currentThread().getName() + " : Inner.m4t1()=" + i);
\r\n                     try {
\r\n                          Thread.sleep(500);
\r\n                     } catch(InterruptedException ie) {
\r\n                     }
\r\n                }
\r\n           }
\r\n           private void m4t2() {
\r\n                int i = 5;
\r\n                while(i-- > 0) {
\r\n                     System.out.println(Thread.currentThread().getName() + " : Inner.m4t2()=" + i);
\r\n                     try {
\r\n                          Thread.sleep(500);
\r\n                     } catch(InterruptedException ie) {
\r\n                     }
\r\n                }
\r\n           }
\r\n      }
\r\n      private void m4t1(Inner inner) {
\r\n           synchronized(inner) { //使用对象锁
\r\n           inner.m4t1();
\r\n      }
\r\n      private void m4t2(Inner inner) {
\r\n           inner.m4t2();
\r\n      }
\r\n      public static void main(String[] args) {
\r\n           final Thread3 myt3 = new Thread3();
\r\n           final Inner inner = myt3.new Inner();
\r\n           Thread t1 = new Thread( new Runnable() {public void run() { myt3.m4t1(inner);} }, "t1");
\r\n      Thread t2 = new Thread( new Runnable() {public void run() { myt3.m4t2(inner);} }, "t2");
\r\n      t1.start();
\r\n      t2.start();
\r\n   }
\r\n }

\r\n

\r\n 结果:

\r\n

\r\n 尽管线程t1获得了对Inner的对象锁,但由于线程t2访问的是同一个Inner中的非同步部分。所以两个线程互不干扰。

\r\n

\r\n      t1 : Inner.m4t1()=4 
\r\n      t2 : Inner.m4t2()=4 
\r\n      t1 : Inner.m4t1()=3 
\r\n      t2 : Inner.m4t2()=3 
\r\n      t1 : Inner.m4t1()=2 
\r\n      t2 : Inner.m4t2()=2 
\r\n      t1 : Inner.m4t1()=1 
\r\n      t2 : Inner.m4t2()=1 
\r\n      t1 : Inner.m4t1()=0 
\r\n      t2 : Inner.m4t2()=0

\r\n

\r\n 现在在Inner.m4t2()前面加上synchronized:

\r\n

\r\n      private synchronized void m4t2() { 
\r\n           int i = 5; 
\r\n           while(i-- > 0) { 
\r\n                System.out.println(Thread.currentThread().getName() + " : Inner.m4t2()=" + i); 
\r\n                try { 
\r\n                     Thread.sleep(500); 
\r\n                } catch(InterruptedException ie) { 
\r\n                } 
\r\n           } 
\r\n      }

\r\n

\r\n 结果:

\r\n

\r\n 尽管线程t1与t2访问了同一个Inner对象中两个毫不相关的部分,但因为t1先获得了对Inner的对象锁,所以t2对Inner.m4t2()的访问也被阻塞,因为m4t2()是Inner中的一个同步方法。

\r\n

\r\n      t1 : Inner.m4t1()=4 
\r\n      t1 : Inner.m4t1()=3 
\r\n      t1 : Inner.m4t1()=2 
\r\n      t1 : Inner.m4t1()=1 
\r\n      t1 : Inner.m4t1()=0 
\r\n      t2 : Inner.m4t2()=4 
\r\n      t2 : Inner.m4t2()=3 
\r\n      t2 : Inner.m4t2()=2 
\r\n      t2 : Inner.m4t2()=1 
\r\n      t2 : Inner.m4t2()=0

\r\n

\r\n 第二篇:

\r\n

\r\n synchronized 关键字,它包括两种用法:synchronized 方法和 synchronized 块。 
\r\n 1. synchronized 方法:通过在方法声明中加入 synchronized关键字来声明 synchronized 方法。如: 
\r\n public synchronized void accessVal(int newVal); 
\r\n synchronized 方法控制对类成员变量的访问:每个类实例对应一把锁,每个 synchronized 方法都必须获得调用该方法的类实例的锁方能

\r\n

\r\n 执行,否则所属线程阻塞,方法一旦执行,就独占该锁,直到从该方法返回时才将锁释放,此后被阻塞的线程方能获得该锁,重新进入可执行

\r\n

\r\n 状态。这种机制确保了同一时刻对于每一个类实例,其所有声明为 synchronized 的成员函数中至多只有一个处于可执行状态(因为至多只有

\r\n

\r\n 一个能够获得该类实例对应的锁),从而有效避免了类成员变量的访问冲突(只要所有可能访问类成员变量的方法均被声明为 synchronized)

\r\n

\r\n 。 
\r\n 在 Java 中,不光是类实例,每一个类也对应一把锁,这样我们也可将类的静态成员函数声明为 synchronized ,以控制其对类的静态成

\r\n

\r\n 员变量的访问。 
\r\n synchronized 方法的缺陷:若将一个大的方法声明为synchronized 将会大大影响效率,典型地,若将线程类的方法 run() 声明为

\r\n

\r\n synchronized ,由于在线程的整个生命期内它一直在运行,因此将导致它对本类任何 synchronized 方法的调用都永远不会成功。当然我们可

\r\n

\r\n 以通过将访问类成员变量的代码放到专门的方法中,将其声明为 synchronized ,并在主方法中调用来解决这一问题,但是 Java 为我们提供

\r\n

\r\n 了更好的解决办法,那就是 synchronized 块。 
\r\n 2. synchronized 块:通过 synchronized关键字来声明synchronized 块。语法如下: 
\r\n synchronized(syncObject) { 
\r\n //允许访问控制的代码 
\r\n } 
\r\n synchronized 块是这样一个代码块,其中的代码必须获得对象 syncObject (如前所述,可以是类实例或类)的锁方能执行,具体机

\r\n

\r\n 制同前所述。由于可以针对任意代码块,且可任意指定上锁的对象,故灵活性较高。 
\r\n 对synchronized(this)的一些理解
\r\n 一、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线

\r\n

\r\n 程必须等待当前线程执行完这个代码块以后才能执行该代码块。 
\r\n 二、然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized

\r\n

\r\n (this)同步代码块。 
\r\n 三、尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)

\r\n

\r\n 同步代码块的访问将被阻塞。 
\r\n 四、第三个例子同样适用其它同步代码块。也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个

\r\n

\r\n object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。 
\r\n 五、以上规则对其它对象锁同样适用

\r\n

\r\n
\r\n java中synchronized用法:

\r\n

\r\n       打个比方:一个object就像一个大房子,大门永远打开。房子里有 很多房间(也就是方法)。

\r\n

\r\n 这些房间有上锁的(synchronized方法), 和不上锁之分(普通方法)。房门口放着一把钥匙(key),这把钥匙可以打开所有上锁的房间。

\r\n

\r\n       另外我把所有想调用该对象方法的线程比喻成想进入这房子某个 房间的人。所有的东西就这么多了,下面我们看看这些东西之间如何作用的。

\r\n

\r\n       在此我们先来明确一下我们的前提条件。该对象至少有一个synchronized方法,否则这个key还有啥意义。当然也就不会有我们的这个主题了。

\r\n

\r\n       一个人想进入某间上了锁的房间,他来到房子门口,看见钥匙在那儿(说明暂时还没有其他人要使用上锁的房间)。于是他走上去拿到了钥匙

\r\n

\r\n ,并且按照自己 的计划使用那些房间。注意一点,他每次使用完一次上锁的房间后会马上把钥匙还回去。即使他要连续使用两间上锁的房间,

\r\n

\r\n 中间他也要把钥匙还回去,再取回来。

\r\n

\r\n       因此,普通情况下钥匙的使用原则是:“随用随借,用完即还。”

\r\n

\r\n       这时其他人可以不受限制的使用那些不上锁的房间,一个人用一间可以,两个人用一间也可以,没限制。但是如果当某个人想要进入上锁的房间,他就要跑到大门口去看看了。有钥匙当然拿了就走,没有的话,就只能等了。

\r\n

\r\n 要是很多人在等这把钥匙,等钥匙还回来以后,谁会优先得到钥匙?Not guaranteed。象前面例子里那个想连续使用两个上锁房间的家伙,他

\r\n

\r\n 中间还钥匙的时候如果还有其他人在等钥匙,那么没有任何保证这家伙能再次拿到。 (JAVA规范在很多地方都明确说明不保证,象

\r\n

\r\n Thread.sleep()休息后多久会返回运行,相同优先权的线程那个首先被执行,当要访问对象的锁被 释放后处于等待池的多个线程哪个会优先得

\r\n

\r\n 到,等等。我想最终的决定权是在JVM,之所以不保证,就是因为JVM在做出上述决定的时候,绝不是简简单单根据 一个条件来做出判断,而是

\r\n

\r\n 根据很多条。而由于判断条件太多,如果说出来可能会影响JAVA的推广,也可能是因为知识产权保护的原因吧。SUN给了个不保证 就混过去了

\r\n

\r\n 。无可厚非。但我相信这些不确定,并非完全不确定。因为计算机这东西本身就是按指令运行的。即使看起来很随机的现象,其实都是有规律

\r\n

\r\n 可寻。学过计算机的都知道,计算机里随机数的学名是伪随机数,是人运用一定的方法写出来的,看上去随机罢了。另外,或许是因为要想弄

\r\n

\r\n 的确定太费事,也没多大意义,所 以不确定就不确定了吧。)

\r\n

\r\n 再来看看同步代码块。和同步方法有小小的不同。

\r\n

\r\n 1.从尺寸上讲,同步代码块比同步方法小。你可以把同步代码块看成是没上锁房间里的一块用带锁的屏风隔开的空间。

\r\n

\r\n 2.同步代码块还可以人为的指定获得某个其它对象的key。就像是指定用哪一把钥匙才能开这个屏风的锁,你可以用本房的钥匙;你也可以指定

\r\n

\r\n 用另一个房子的钥匙才能开,这样的话,你要跑到另一栋房子那儿把那个钥匙拿来,并用那个房子的钥匙来打开这个房子的带锁的屏风。

\r\n

\r\n          记住你获得的那另一栋房子的钥匙,并不影响其他人进入那栋房子没有锁的房间。

\r\n

\r\n          为什么要使用同步代码块呢?我想应该是这样的:首先对程序来讲同步的部分很影响运行效率,而一个方法通常是先创建一些局部变

\r\n

\r\n 量,再对这些变量做一些 操作,如运算,显示等等;而同步所覆盖的代码越多,对效率的影响就越严重。因此我们通常尽量缩小其影响范围。

\r\n

\r\n 如何做?同步代码块。我们只把一个方法中该同 步的地方同步,比如运算。

\r\n

\r\n          另外,同步代码块可以指定钥匙这一特点有个额外的好处,是可以在一定时期内霸占某个对象的key。还记得前面说过普通情况下钥

\r\n

\r\n 匙的使用原则吗。现在不是普通情况了。你所取得的那把钥匙不是永远不还,而是在退出同步代码块时才还。

\r\n

\r\n           还用前面那个想连续用两个上锁房间的家伙打比方。怎样才能在用完一间以后,继续使用另一间呢。用同步代码块吧。先创建另外

\r\n

\r\n 一个线程,做一个同步代码 块,把那个代码块的锁指向这个房子的钥匙。然后启动那个线程。只要你能在进入那个代码块时抓到这房子的钥匙

\r\n

\r\n ,你就可以一直保留到退出那个代码块。也就是说 你甚至可以对本房内所有上锁的房间遍历,甚至再sleep(10*60*1000),而房门口却还有

\r\n

\r\n 1000个线程在等这把钥匙呢。很过瘾吧。

\r\n

\r\n           在此对sleep()方法和钥匙的关联性讲一下。一个线程在拿到key后,且没有完成同步的内容时,如果被强制sleep()了,那key还一

\r\n

\r\n 直在 它那儿。直到它再次运行,做完所有同步内容,才会归还key。记住,那家伙只是干活干累了,去休息一下,他并没干完他要干的事。为

\r\n

\r\n 了避免别人进入那个房间 把里面搞的一团糟,即使在睡觉的时候他也要把那唯一的钥匙戴在身上。

\r\n

\r\n           最后,也许有人会问,为什么要一把钥匙通开,而不是一个钥匙一个门呢?我想这纯粹是因为复杂性问题。一个钥匙一个门当然更

\r\n

\r\n 安全,但是会牵扯好多问题。钥匙 的产生,保管,获得,归还等等。其复杂性有可能随同步方法的增加呈几何级数增加,严重影响效率。这也

\r\n

\r\n 算是一个权衡的问题吧。为了增加一点点安全性,导致效 率大大降低,是多么不可取啊。

\r\n

\r\n synchronized的一个简单例子

\r\n

\r\n public class TextThread {

\r\n

\r\n public static void main(String[] args) {
\r\n    TxtThread tt = new TxtThread();
\r\n    new Thread(tt).start();
\r\n    new Thread(tt).start();
\r\n    new Thread(tt).start();
\r\n    new Thread(tt).start();
\r\n }
\r\n }

\r\n

\r\n class TxtThread implements Runnable {
\r\n int num = 100;
\r\n String str = new String();

\r\n

\r\n public void run() {
\r\n    synchronized (str) {
\r\n     while (num > 0) {

\r\n

\r\n      try {
\r\n       Thread.sleep(1);
\r\n      } catch (Exception e) {
\r\n       e.getMessage();
\r\n      }
\r\n      System.out.println(Thread.currentThread().getName()
\r\n        + "this is " + num--);
\r\n     }
\r\n    }
\r\n }
\r\n }

\r\n

\r\n 上面的例子中为了制造一个时间差,也就是出错的机会,使用了Thread.sleep(10)

\r\n

\r\n Java对多线程的支持与同步机制深受大家的喜爱,似乎看起来使用了synchronized关键字就可以轻松地解决多线程共享数据同步问题。到底如

\r\n

\r\n 何?――还得对synchronized关键字的作用进行深入了解才可定论。

\r\n

\r\n 总的说来,synchronized关键字可以作为函数的修饰符,也可作为函数内的语句,也就是平时说的同步方法和同步语句块。如果再细的分类,

\r\n

\r\n synchronized可作用于instance变量、object reference(对象引用)、static函数和class literals(类名称字面常量)身上。

\r\n

\r\n 在进一步阐述之前,我们需要明确几点:

\r\n

\r\n A.无论synchronized关键字加在方法上还是对象上,它取得的锁都是对象,而不是把一段代码或函数当作锁――而且同步方法很可能还会被其

\r\n

\r\n 他线程的对象访问。

\r\n

\r\n B.每个对象只有一个锁(lock)与之相关联。

\r\n

\r\n C.实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制。

\r\n

\r\n 接着来讨论synchronized用到不同地方对代码产生的影响:

\r\n

\r\n 假设P1、P2是同一个类的不同对象,这个类中定义了以下几种情况的同步块或同步方法,P1、P2就都可以调用它们。

\r\n

\r\n 1. 把synchronized当作函数修饰符时,示例代码如下:

\r\n

\r\n Public synchronized void methodAAA()

\r\n

\r\n {

\r\n

\r\n //….

\r\n

\r\n }

\r\n

\r\n 这也就是同步方法,那这时synchronized锁定的是哪个对象呢?它锁定的是调用这个同步方法对象。也就是说,当一个对象P1在不同的线程中

\r\n

\r\n 执行这个同步方法时,它们之间会形成互斥,达到同步的效果。但是这个对象所属的Class所产生的另一对象P2却可以任意调用这个被加了

\r\n

\r\n synchronized关键字的方法。

\r\n

\r\n 上边的示例代码等同于如下代码:

\r\n

\r\n public void methodAAA()

\r\n

\r\n {

\r\n

\r\n synchronized (this)      // (1)

\r\n

\r\n {

\r\n

\r\n        //…..

\r\n

\r\n }

\r\n

\r\n }

\r\n

\r\n (1)处的this指的是什么呢?它指的就是调用这个方法的对象,如P1。可见同步方法实质是将synchronized作用于object reference。――那个

\r\n

\r\n 拿到了P1对象锁的线程,才可以调用P1的同步方法,而对P2而言,P1这个锁与它毫不相干,程序也可能在这种情形下摆脱同步机制的控制,造

\r\n

\r\n 成数据混乱:(

\r\n

\r\n 2.同步块,示例代码如下:

\r\n

\r\n public void method3(SomeObject so)

\r\n

\r\n {

\r\n

\r\n     synchronized(so)

\r\n

\r\n     {
\r\n        //…..
\r\n     }

\r\n

\r\n }

\r\n

\r\n 这时,锁就是so这个对象,谁拿到这个锁谁就可以运行它所控制的那段代码。当有一个明确的对象作为锁时,就可以这样写程序,但当没有明

\r\n

\r\n 确的对象作为锁,只是想让一段代码同步时,可以创建一个特殊的instance变量(它得是一个对象)来充当锁:

\r\n

\r\n class Foo implements Runnable

\r\n

\r\n {

\r\n

\r\n         private byte[] lock = new byte[0]; // 特殊的instance变量

\r\n

\r\n         Public void methodA()
\r\n         {

\r\n

\r\n            synchronized(lock) { //… }

\r\n

\r\n         }

\r\n

\r\n         //…..

\r\n

\r\n }

\r\n

\r\n 注:零长度的byte数组对象创建起来将比任何对象都经济――查看编译后的字节码:生成零长度的byte[]对象只需3条操作码,而Object lock

\r\n

\r\n = new Object()则需要7行操作码。

\r\n

\r\n 3.将synchronized作用于static 函数,示例代码如下:

\r\n

\r\n Class Foo
\r\n {

\r\n

\r\n     public synchronized static void methodAAA()   // 同步的static 函数
\r\n     {
\r\n         //….
\r\n     }

\r\n

\r\n     public void methodBBB()
\r\n     {

\r\n

\r\n        synchronized(Foo.class)   // class literal(类名称字面常量)

\r\n

\r\n     }
\r\n }

\r\n

\r\n    代码中的methodBBB()方法是把class literal作为锁的情况,它和同步的static函数产生的效果是一样的,取得的锁很特别,是当前调用这

\r\n

\r\n 个方法的对象所属的类(Class,而不再是由这个Class产生的某个具体对象了)。

\r\n

\r\n 记得在《Effective Java》一书中看到过将 Foo.class和 P1.getClass()用于作同步锁还不一样,不能用P1.getClass()来达到锁这个Class的

\r\n

\r\n 目的。P1指的是由Foo类产生的对象。

\r\n

\r\n 可以推断:如果一个类中定义了一个synchronized的static函数A,也定义了一个synchronized 的instance函数B,那么这个类的同一对象Obj

\r\n

\r\n 在多线程中分别访问A和B两个方法时,不会构成同步,因为它们的锁都不一样。A方法的锁是Obj这个对象,而B的锁是Obj所属的那个Class。

\r\n

\r\n 小结如下:

\r\n

\r\n 搞清楚synchronized锁定的是哪个对象,就能帮助我们设计更安全的多线程程序。

\r\n

\r\n 还有一些技巧可以让我们对共享资源的同步访问更加安全:

\r\n

\r\n 1. 定义private 的instance变量+它的 get方法,而不要定义public/protected的instance变量。如果将变量定义为public,对象在外界可以

\r\n

\r\n 绕过同步方法的控制而直接取得它,并改动它。这也是JavaBean的标准实现方式之一。

\r\n

\r\n 2. 如果instance变量是一个对象,如数组或ArrayList什么的,那上述方法仍然不安全,因为当外界对象通过get方法拿到这个instance对象

\r\n

\r\n 的引用后,又将其指向另一个对象,那么这个private变量也就变了,岂不是很危险。 这个时候就需要将get方法也加上synchronized同步,并

\r\n

\r\n 且,只返回这个private对象的clone()――这样,调用端得到的就是对象副本的引用了

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2790, 'introduction-to-jgoodies-formlayout-a', 'Jgoodies FormLayout入门(一)', '2012-12-18 18:31:21', '2019-03-25 21:29:22', '

\r\n
\r\n 一、列与行的参数都由三个部分组成:对齐方式、固定尺寸、调整方式。
\r\n 1.对齐方式:
\r\n 1)列对齐有left, center, right, fill.默认fill
\r\n 2)行对齐有:top, center, bottom, fill. 其中fill表示填充至整个区域。默认center。
\r\n 2.固定尺寸:
\r\n pref表示preferred size,适当大小,即首选尺寸大小。
\r\n min表示minimum size,
\r\n dlu 表示dialog units,
\r\n px, pt, in, mm, cm)分别表示Pixel, Points, Inches, Millimeter, Centimeter。
\r\n 3. 调整方式:
\r\n 二、CellConstraints:
\r\n cc.xywh(3, 1, 3, 1):表示3列,1行,colspan=3,rowspan=1
\r\n 三、FormLayout:
\r\n   1.FormLayout layout = new FormLayout(
\r\n    new ColumnSpec[]{
\r\n      FormSpecs.DEFAULT_COLSPEC,
\r\n      FormSpecs.GLUE_COLSPEC,
\r\n      FormSpecs.DEFAULT_COLSPEC,
\r\n      FormSpecs.GLUE_COLSPEC,
\r\n      FormSpecs.DEFAULT_COLSPEC,
\r\n      FormSpecs.GLUE_COLSPEC},
\r\n    new RowSpec[]{
\r\n      FormSpecs.DEFAULT_ROWSPEC,
\r\n      FormSpecs.GLUE_ROWSPEC,
\r\n      FormSpecs.DEFAULT_ROWSPEC,
\r\n      FormSpecs.GLUE_ROWSPEC,
\r\n      FormSpecs.DEFAULT_ROWSPEC,
\r\n      FormSpecs.GLUE_ROWSPEC
\r\n    }
\r\n   );
\r\n 2.

\r\n  

\r\n

\r\n FormLayout layout = new FormLayout( 
\r\n         "right:pref, 6dlu, 50dlu, 4dlu, center:50dlu", // columns
\r\n         "pref, 3dlu, pref, 3dlu, pref"); // rows   

\r\n

\r\n
\r\n
\r\n  

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2791, 'iis7-web-site-publishing-error-pagehandlerfactory-integrated-in-its-module-list-there-is-an-error-in-the-module-mana', 'IIS7网站发布错误“PageHandlerFactory-Integrated”在其模块列表中有一个错误模块“Mana', '2012-12-14 02:09:43', '2019-03-25 21:29:22', '

\r\n 今天安装了windows7

\r\n

\r\n 开发web项目需要安装IIS,当安装完以后,web程序已经映射到了本地IIS上,运行出现如下错误提示

\r\n

\r\n 处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误模块“ManagedPipelineHandler”

\r\n

\r\n 原因:

\r\n

\r\n vs2010默认的是4.0框架,4.0的框架是独立的CLR,和2.0的不同,如果想运行4.0的网站,需要用aspnet_regiis注册4.0框架,然后用4.0的Class池,就可以运行4.0的web项目了.

\r\n

\r\n 如何用aspnet_regiis注册4.0框架 :

\r\n

\r\n 方法如下,启动cmd (win键+R 启动cmd)  ,找到 4.0所在的目录,本人机器目录是 ;
\r\n
\r\n 注意:要以管理员的身份运行DOS窗口。

\r\n

\r\n \"处理程序鈥淧ageHandlerFactory-Integrated鈥澰谄淠?榱斜碇杏幸桓龃砦竽?\"
\r\n  

\r\n

\r\n 复制上面的目录  C:WindowsMicrosoft.NETFrameworkv4.0.30319

\r\n

\r\n 启动CMD进入上面的目录,如下图

\r\n

\r\n \"处理程序鈥淧ageHandlerFactory-Integrated鈥澰谄淠?榱斜碇杏幸桓龃砦竽?\"

\r\n

\r\n 回车后 如下图
\r\n
\r\n \"处理程序鈥淧ageHandlerFactory-Integrated鈥澰谄淠?榱斜碇杏幸桓龃砦竽?\"

\r\n

\r\n 已经进入 C:WindowsMicrosoft.NETFrameworkv4.0.30319 此目录

\r\n

\r\n 然后运行  aspnet_regiis.exe -i  如下图

\r\n

\r\n \"处理程序鈥淧ageHandlerFactory-Integrated鈥澰谄淠?榱斜碇杏幸桓龃砦竽?\"

\r\n

\r\n 稍等一会,  aspnet_regiis 注册后如下图

\r\n

\r\n \"处理程序鈥淧ageHandlerFactory-Integrated鈥澰谄淠?榱斜碇杏幸桓龃砦竽?\"

\r\n

\r\n ok,这时的IIS就可以运行 .net 4.0 部署的网站了.

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2792, 'chinese-errors-in-python-syntaxerrornon-ascii-character-xxx-in-file-x', 'Python中中文出现错误:SyntaxError: Non-ASCII character xxx in file x', '2012-12-10 12:34:38', '2019-03-25 21:29:22', '在文件头部添加:
\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n#!/usr/bin/python\r\n# -*- coding: utf-8 -*-
\r\n
\r\n问题解决。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2793, 'modify-the-sa-users-to-use-sql-statements-to-login-password', '用sql语句来修改sa用户的登陆密码', '2012-11-29 22:26:07', '2019-03-25 21:29:22', '
\r\n

步骤一:
打开sql server manager studio,用Windows验证登陆,新建查询,执行以下语句:

\r\n

步骤二:

\r\n

1)打开对象资源管理器视图,在数据库链接上右键->属性。

\r\n

2)在打开的窗口点击安全性,将sql server和windows身份验证模式勾上。

\r\n

3)展开安全性菜单,将登陆名下的sa属性-状态-登陆-启用

\r\n
\r\n

 alter login sa with password=’你的新密码’

\r\n
\r\n

3然后把mssql server服务重启一下,很重要!!!

\r\n

到此OK,开始登录吧!

\r\n

 

\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2794, 'design-patterns-strategy-pattern', '设计模式之策略模式', '2012-11-26 23:50:14', '2019-03-25 21:29:22', '

\r\n 问题:
\r\n    软件开发中常常遇到类似的情况,实现某一个功能有多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能。对于这种情况,你打算怎么做?

\r\n \"\"
\r\n 传统做法一:
\r\n       一种常用的方法是硬编码(Hard Coding)。即在一个类中,如需要提供多种算法,可以将这些算法写到一个类中,在该类中提供多个方法,每一个方法对应一个具体的算法;
\r\n \"\"
\r\n 传统做法二:
\r\n       将这些查找算法封装在一个统一的方法中,通过if…else…或者switch~case等条件判断语句来进行选择
\r\n \"\"
\r\n 传统做法的弊端:
\r\n       以上两类代码实现时将较变得十分复杂,维护较为困难。如果我们将这些策略包含在客户端,这种做法更不可取,将导致客户端程序庞大而且难以维护,如果存在大量可供选择的算法时问题将变得更加严重。
\r\n 解决方案:
\r\n       使用策略模式。
\r\n 当存在以下情况时使用Strategy模式:
\r\n 1)许多相关的类仅仅是行为有异。 “策略”提供了一种用多个行为中的一个行为来配置一个类的方法。即一个系统需要动态地在几种算法中选择一种。
\r\n 2)需要使用一个算法的不同变体。例如,你可能会定义一些反映不同的空间 /时间权衡的算法。当这些变体实现为一个算法的类层次时 ,可以使用策略模式。
\r\n 3)算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构。
\r\n 4)一个类定义了多种行为 , 并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的Strategy类中以代替这些条件语句。
\r\n 策略模式的结构如下图:
\r\n \"\"
\r\n 出行旅游:
\r\n       现在有一个出行旅游的场景,其中游客可以选择不同的交通工具。
\r\n 分析:
\r\n       虽然用户可以使用不同的交通工具,但最终目的都是去旅游,即这些旅游策略相关并且仅仅行为有异,并且由于只要到达目的地,使用任何交通工具都可以,因此,他们彼此可以相互替换,符合策略模式的定义,因此,可以采用策略模式来实现。
\r\n UML图如下:
\r\n \"\"
\r\n       其中,Client为客户端,Person为环境角色(Context),Strategy为抽象策略角色(Strategy),其余的四个均为具体策略角色。
\r\n 程序类结构:
\r\n \"\"
\r\n Strategy.java
\r\n \"\"
\r\n Person.java
\r\n \"\"
\r\n BicycleStrategy.java
\r\n \"\"
\r\n BusStrategy.java
\r\n \"\"
\r\n TrainStrategy.java
\r\n \"\"
\r\n AirPlaneStrategy.java
\r\n \"\"
\r\n 调用自行车策略:
\r\n \"\"
\r\n 调用公共汽车策略:
\r\n \"\"
\r\n 调用火车策略:
\r\n \"\"
\r\n 调用乘飞机策略:
\r\n \"\"
\r\n 策略模式的优点:
\r\n 1)Strategy类层次为Context定义了一系列的可供重用的算法或行为。 继承有助于析取出这些算法中的公共功能。
\r\n 2)提供了可以替换继承关系的办法
\r\n 3) 消除了一些if else条件语句
\r\n 策略模式的缺点:
\r\n 1)客户端必须知道所有的策略类,并自行决定使用哪一个策略类
\r\n 2 ) Strategy和Context之间的通信开销
\r\n 3 )策略模式将造成产生很多策略类

\r\n
\r\n  

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2795, 'database-design-multi-user-group-permissions-management-issues', '20131218192655', '2012-11-26 23:33:36', '2019-03-25 21:29:22', '一般分组管理设计三个表 \r\n1 功能表        \r\nf_id  功能ID号\r\nf_name 功能名称(添加 删除 修改) \r\nf_description(描述) \r\n\r\n2 用户组表                     \r\ngroup_id 组ID号 \r\ngroup_name   \r\n group_power(功能表ID的集合) \r\n3 用户表                         \r\nuser_id   \r\nuser_name   \r\nuser_pwd   \r\nuser_groupId \r\n设计这三张表  管理权限由用户组表的功能集合决定。\r\n\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2796, 'ubuntu-11-10-install-jdk-1-6', 'ubuntu 11.10安装jdk 1.6', '2012-11-24 21:04:51', '2019-03-25 21:29:22', '

\r\n    安装了ubuntu 11.10之后,由于库里没有sun-java6-jdk,需要自行安装。因此,到Oracle网站下载了Java 6u29(为什么不下java7呢?因为目前支持的软件不多,另外如果真要的话,也可以很方便的切换到Java7),然后就可以开始手动安装了。
\r\n jdk 1.6的下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk-6u29-download-513648.html

\r\n

\r\n    选择Linux x86对应链接,注意不要选择rpm.bin的,选择.bin。下载之后放到主文件夹中。
\r\n \"\"
\r\n
\r\n    首先创建Java的目录,然后将下载下来的文件解压到该目录中

\r\n  

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n$ cd /usr/lib\r\n$ sudo mkdir jvm\r\n$ sudo chmod 777 /usr/lib/jvm\r\n$ sudo cp /home/administrator/jdk-6u29-linux-i586.bin /usr/lib/jvm\r\n$ cd /usr/lib/jvm\r\n\r\n$ sudo chmod 777 jdk-6u29-linux-i586.bin  (这一步不要漏了,修改文件的访问权限)\r\n$ sudo ./jdk-6u29-linux-i586.bin
\r\n
\r\n 
\r\n   安装成功后出现以下界面:
\r\n
\r\n\"\"

\r\n

\r\n    其次设置环境变量,主要是PATH、CLASSPATH和JAVA_HOME,注意PATH最后所添加的bin目录:
\r\n  

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n$ sudo gedit /etc/profile\r\n\r\n将打开的内容改成下面的:\r\nexport JAVA_HOME=/usr/lib/jvm/jdk1.6.0_29\r\nexport PATH=$JAVA_HOME/bin:$PATH\r\nexport CLASSPATH=.:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar:$CLASSPATH
\r\n
\r\n

\r\n
\r\n     注意:配置环境变量这一步很重要,我就是开始没有配置好导致了java命令一直不能被识别)
\r\n     最后就是设置更新,注意下面的2行命令 --install后面一个四个参数 分别是 链接 名称 路径 优先级,我们只要修改对应的路径就可以了,其他我没动)

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n$ sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/jdk1.6.0_29//bin/java 300\r\n$ sudo update-alternatives --install /usr/bin/javac javac/usr/lib/jvm/jdk1.6.0_29/bin/javac 300
\r\n
\r\n
\r\n

\r\n 如上所示,这样就设置好了要使用的java了。最后我们验证一下:
\r\n  

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n$ java -version
\r\n
\r\n

\r\n \"\"
\r\n    
\r\n    到此为止,恭喜你,你已经成安装了jdk1.6,开始你在Linux上的java之旅吧!

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2797, 'ubuntu-theme-engine-cannot-be-found-in-the-module-path-pixmap', 'Ubuntu无法在模块路径中找到主题引擎:“pixmap”', '2012-11-25 04:56:38', '2019-03-25 21:29:22', '

\r\n    打开virt-manager提示:Gtk-WARNING**: 无法在模块路径中找到主题引擎:“pixmap”?

\r\n

\r\n    这是gtk引擎出了问题,安装gtk引擎即可,命令:sudo apt-get install gtk2-engines-pixbuf
\r\n \"\"

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2798, 'ubuntu-install-adobe-flash-player', 'Ubuntu 12.04安装Adobe Flash Player', '2013-11-17 18:13:37', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

\r\n

下载。

\r\n

打开http://get.adobe.com/cn/flashplayer/,下载相应linux版本(注意一定要下载.tar.gz版本的)。下载后的得到文件:install_flash_player_11_linux.x86_64.tar.gz

\r\n

\"2013-11-16T07-11-45.641Z\" 

\r\n

解压缩安装包到主文件夹

\r\n

打开终端(Ctrl+Alt+T),进入刚下载的文件目录,输入以下命令:

\r\n

\r\n
    \r\n
  1. tar -xzvf install_flash_player_11_linux.x86_64.tar.gz 
  2. \r\n
\r\n

结果如图:

\r\n

\r\n

\"\"

\r\n

 

\r\n

\"\"

\r\n

拷贝libflashplayer.so

\r\n

在终端输入:

\r\n

\r\n
    \r\n
  1. sudo cp libflashplayer.so /usr/lib/mozilla/plugins 
  2. \r\n
\r\n

 

\r\n

查看。

\r\n

\"\"

\r\n

可以看到libflashplayer.so已经在里面了。

\r\n

安装nspluginwrapper。

\r\n
    \r\n
  1. sudo apt-get install nspluginwrapper   
  2. \r\n
\r\n

执行以下命令。

\r\n
    \r\n
  1. nspluginwrapper -i /usr/lib/mozilla/plugins/libflashplayer.so 
  2. \r\n
\r\n

运行网页实验,发现已经可以了。

\r\n

(PS:貌似6、7步可以不做,也能看视频,目前还没找着原因)

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2799, 'design-pattern-the-singleton', '设计模式之单例模式', '2012-11-20 15:10:53', '2019-03-25 21:29:22', '

\r\n    单例模式是对象的创建模式之一,此外还包括工厂模式。单例模式的三个特点:
\r\n    1、该类只有一个实例
\r\n    2、该类自行创建该实例(在该类内部创建自身的实例对象);
\r\n    3、向整个系统公开这个实例接口

\r\n    Java中的代码实现:

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n/**\r\n * @home:http://www.xinValue.com\r\n * @author Tangyouwei\r\n * @mail cyutyw@126.com\r\n * @qq 1035136784\r\n */\r\nclass Singleton {\r\n\r\n    //私有,静态的类自身实例\r\n    private static Singleton instance = new Singleton();\r\n\r\n    //私有的构造子(构造器,构造函数,构造方法)\r\n    private Singleton(){}\r\n\r\n    //公开,静态的工厂方法\r\n    public static Singleton getInstance() {\r\n        return instance;\r\n    }\r\n}
\r\n
\r\n

\r\n
\r\n       测试类:

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n/**\r\n * @home:http://www.xinValue.com\r\n * @author Tangyouwei\r\n * @mail cyutyw@126.com\r\n * @qq 1035136784\r\n */\r\npublic class SingletonTest\r\n{\r\n\r\n    public static void main(String[] args)\r\n    {\r\n        Singleton sg = Singleton.getInstance();\r\n        Singleton sg2 = Singleton.getInstance();\r\n        System.out.println(sg == sg2);\r\n    }\r\n}
\r\n
\r\n

\r\n       效果:
\r\n \"\"

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2800, 'android-in-the-transition-between-dp-and-px', 'Android中dp和px之间的转换', '2012-11-15 21:56:58', '2019-03-25 21:29:22', '

\r\n       在xml布局文件中,我们既可以设置px,也可以设置dp(或者dip)。一般情况下,我们都会选择使用dp,这样可以保证不同屏幕分辨率的机器上 布局一致。但是在代码中,如何处理呢?很多控件的方法中都只提供了设置px的方法,例如setPadding,并没有提供设置dp的方法。这个时候,如果 需要设置dp的话,就要将dp转换成px了。

\r\n

\r\n       以下是一个应用类,方便进行px和dp之间的转换。
\r\n  

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\nimport android.content.Context;\r\n\r\npublic class DensityUtil {\r\n\r\n	/**\r\n	 * 根据手机的分辨率从 dp 的单位 转成为 px(像素)\r\n	 */\r\n	public static int dip2px(Context context, float dpValue) {\r\n		final float scale = context.getResources().getDisplayMetrics().density;\r\n		return (int) (dpValue * scale + 0.5f);\r\n	}\r\n\r\n	/**\r\n	 * 根据手机的分辨率从 px(像素) 的单位 转成为 dp\r\n	 */\r\n	public static int px2dip(Context context, float pxValue) {\r\n		final float scale = context.getResources().getDisplayMetrics().density;\r\n		return (int) (pxValue / scale + 0.5f);\r\n	}\r\n}
\r\n
\r\n
\r\n本文转载自:http://my.oschina.net/liux/blog/50427
\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2801, 'android-development-issues-avoid-using-px-as-units-use-dp-instead', '安卓开发问题:Avoid using "px" as units; use "dp" instead', '2012-11-15 21:49:51', '2019-03-25 21:29:22', '
\r\n情景重现\r\n======\r\n**Eclipse版本** **3.7.1**\r\n**Adt版本16.0.1**\r\n错误警告提示** Avoid using \"px\" as units; use\"dp\" instead**\r\n在编辑main.xml文件之后,存盘时出现以上警告。\r\n解决办法\r\n========\r\n把代码中的px全部改为dp.这个警告主要是提醒你的程序要在不同大小的屏幕上能正常显示的话,还是要使用dp为单位,而不用使用px这个单位。
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2802, 'design-of-quadrilateral-base-class-cquadrangle-and-design-4', '设计四边形基类CQuadrangle,再设计4个...', '2012-11-15 16:39:36', '2019-03-25 21:29:22', '源码:
\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n#include <math.h>\r\n#include <iostream>\r\nusing namespace std;\r\n\r\nclass CQuadrangle//四边形类\r\n{\r\npublic:\r\n    CQuadrangle(int ed)//构造函数\r\n    {\r\n        edge=ed;\r\n    }\r\n    ~CQuadrangle(){}//析构函数\r\n\r\n    int area()//求面积\r\n    {\r\n        return 0;\r\n    }\r\n\r\n    int  Perimeter()//求周长\r\n    {\r\n        return 0;\r\n    }\r\n    int DiagonalLength()//求对角线长\r\n    {\r\n        return 0;\r\n    }\r\n\r\nprotected://成员变量\r\n    int edge;\r\n    int diagonal;\r\n};\r\n\r\nclass Rectangle:public  CQuadrangle//派生长方形类\r\n{\r\npublic:\r\n    Rectangle(int le,int wi):CQuadrangle(le)\r\n    {\r\n        length=le;\r\n        width=wi;\r\n    }\r\n    ~Rectangle(){}\r\n    int area() const\r\n    {\r\n        return length*width;\r\n    }\r\n    int  Perimeter()\r\n    {\r\n        return (width+length)*2;\r\n    }\r\n    float DiagonalLength()\r\n    {\r\n        return sqrt((float)(width*width+length*length));\r\n    }\r\n\r\nprotected:\r\n    int length;\r\n    int width;\r\n    int diagonal;\r\n};\r\n\r\nclass Square:public  CQuadrangle//派生正方形类\r\n{\r\npublic:\r\n    Square(int ed):CQuadrangle(ed)\r\n    {\r\n        edge=ed;\r\n    }\r\n    ~Square(){}\r\n    int area() const\r\n    {\r\n        return edge*edge;\r\n    }\r\n    int  Perimeter()\r\n    {\r\n        return edge*4;\r\n    }\r\n    float DiagonalLength()\r\n    {\r\n        return sqrt(2.0)*edge;//注意,只能写2.0,不能写2,否则VS编译不通过\r\n    }\r\n\r\nprotected:\r\n    int edge;\r\n    int diagonal;\r\n};\r\n\r\nclass Parallelogram:public  CQuadrangle//派生平行四边形类\r\n{\r\npublic:\r\n    Parallelogram(int to,int hi):CQuadrangle(to)\r\n    {\r\n        top=to;\r\n        high=hi;\r\n    }\r\n    ~Parallelogram(){}\r\n    int area()\r\n    {\r\n        return top*high;\r\n    }\r\n\r\nprotected:\r\n    int top;\r\n    int high;\r\n};\r\n\r\nclass Trapezoid:public  CQuadrangle//派生梯形类\r\n{\r\npublic:\r\n    Trapezoid(int u,int dow,int hi):CQuadrangle(u)\r\n    {\r\n        up=u;\r\n        down=dow;\r\n        high=hi;\r\n    }\r\n    ~Trapezoid(){}\r\n    int area() const\r\n    {\r\n        return ((up+down)*high)/2;\r\n    }\r\n\r\nprotected:\r\n    int up;\r\n    int down;\r\n    int high;\r\n};\r\n\r\n\r\nint main()\r\n{\r\n    Rectangle rt(3,2);//长方形测试\r\n    cout<<"测试的长方形长为3,宽为2:"<<endl;\r\n    cout<<"长方形的面积:"<<rt.area()<<endl;\r\n    cout<<"长方形的周长:"<<rt.Perimeter()<<endl;\r\n    cout<<"长方形的对角线长:"<<rt.DiagonalLength()<<endl;\r\n    cout<<endl;\r\n    cout<<"测试的正方形边长为2:"<<endl;\r\n    Square sq(2);//正方形测试\r\n    cout<<"正方形的面积:"<<sq.area()<<endl;\r\n    cout<<"正方形的周长:"<<sq.Perimeter()<<endl;\r\n    cout<<"正方形的对角线长:"<<sq.DiagonalLength()<<endl;\r\n    cout<<endl;\r\n    cout<<"测试的平行四边形底为2,高为3:"<<endl;\r\n    Parallelogram pa(2,3);//平行四边形测试\r\n    cout<<"平行四边形的面积:"<<pa.area()<<endl;\r\n    cout<<endl;\r\n    cout<<"测试的梯形上底为2,下底为3,高为4:"<<endl;\r\n    Trapezoid tp(2,3,4);//梯形测试\r\n    cout<<"梯形的面积:"<<tp.area()<<endl;\r\n    return 0;\r\n}
\r\n
\r\n
\r\n演示:
\r\n\"\"', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2803, 'java-stringbuffer-in-detail', 'Java中的StringBuffer详解', '2012-11-15 16:25:37', '2019-03-25 21:29:22', '
      要知道StringBuffer的用法,必须知道他和String之间的关系,因为你都在StringBuffer了,必然是碰到了String不能解决的问题。\r\n 1、构造函数。\r\nStringBuffer() :构造一个没有任何字符的StringBuffer类。\r\nStringBuffer(int length) : :构造一个没有任何字符的StringBuffer类,并且,其长度为length。\r\nStringBuffer(String str) :以str为初始值构造一个StringBuffer类。\r\n 2、方法。\r\n说明:\r\n所有方法均为public;\r\n书写格式:〔修饰符〕   <返回类型> <方法名(〔参数列表〕)>\r\n如:\r\nstatic int parseInt(String s) 表示:此方法(parseInt)为类方法(static),返回类型为(int),方法所需参数为String类型。1. StringBuffer append(boolean b)\r\n2. StringBuffer append(char c)\r\n3. StringBuffer append(char[] str)\r\n4. StringBuffer append(char[] str, int offset, int len)\r\n5. StringBuffer append(double d)\r\n6. StringBuffer append(float f)\r\n7. StringBuffer append(int i)\r\n8. StringBuffer append(long l)\r\n9. StringBuffer append(Object obj)\r\n10. StringBuffer append(String str)\r\n11. StringBuffer append(StringBuffer sb)\r\n以上的方法都是向字符串缓冲区“追加”元素,但是,这个“元素”参数可以是布尔量、字符、字符数组、双精度数、浮点数、整型数、长整型数对象类型的字符串、字符串和StringBuffer类等。如果添加的字符超出了字符串缓冲区的长度,Java将自动进行扩充。\r\n\r\n\r\n\r\n\r\n\r\n\r\n
\r\n
String question = new String(\"1+1=\");\r\nint answer = 3;\r\nboolean result = (1+1==3);\r\nStringBuffer sb = new StringBuffer();\r\nsb.append(question);\r\nsb.append(answer);\r\nsb.append(‘t‘);\r\nsb.append(result);\r\nSystem.out.println(sb);
\r\n
\r\n结果为:1+1=3    false\r\n\r\n12. int capacity() :返回当前StringBuffer对象(字符串缓冲区)的总空间,而非字符号串的长度。\r\n13. char charAt(int index) :在当前StringBuffer对象中取索引号为index的字符。第一个字符的索引为“0”\r\n14. StringBuffer delete(int start, int end) :删除当前StringBuffer对象中以索引号start开始,到end结束的子串。\r\n15. StringBuffer deleteCharAt(int index) :删除当前StringBuffer对象中索引号为index的字符。\r\n16. void ensureCapacity(int minimumCapacity) :重新设置字符号串缓冲区的总空间。如果minimumCapacity大于当前的总空间,则新的空间被设置:一种结果是minimumCapacity;另一种结果是{“老空间”乘2加2}。\r\n\r\n\r\n\r\n\r\n\r\n\r\n
\r\n
StringBuffer sb1 = new StringBuffer(5);\r\nStringBuffer sb2 = new StringBuffer(5);\r\nsb1.ensureCapacity(6);\r\nsb2.ensureCapacity(100);\r\nSystem.out.println( \"sb1.Capacity: \" + sb1.capacity() );\r\nSystem.out.println( \"sb2.Capacity: \" + sb2.capacity() );
\r\n
\r\n结果为:sb1.Capacity: 12\r\nsb2.Capacity: 100\r\n\r\n17. void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) :从当前StringBuffer对象的索引号srcBegin开始,到srcEnd结束的子串,赋值到字符数组dst中,并且从dst的索引号dstBegin开始。\r\n\r\n\r\n\r\n\r\n\r\n\r\n
\r\n
StringBuffer sb = new StringBuffer(\"I love her!\");\r\nchar[] i = {‘I‘,‘ ‘,‘l‘,‘o‘,‘v‘,‘e‘,‘ ‘,‘y‘,‘o‘,‘u‘};\r\nsb.getChars(7,10,i,7);\r\nSystem.out.println( \"sb: \" + sb );
\r\n
\r\n结果为:sb: I love her!\r\n\r\n18. int indexOf(String str) :返回当前StringBuffer对象中,第一个满足str子串的位置。\r\n19. int indexOf(String str, int fromIndex) :从当前StringBuffer对象的fromIndex开始查找,返回第一个满足str子串的位置。\r\n20. StringBuffer insert(int offset, boolean b)\r\n21. StringBuffer insert(int offset, char c)\r\n22. StringBuffer insert(int offset, char[] str)\r\n23. StringBuffer insert(int index, char[] str, int offset, int len)\r\n24. StringBuffer insert(int offset, double d)\r\n25. StringBuffer insert(int offset, float f)\r\n26. StringBuffer insert(int offset, int i)\r\n27. StringBuffer insert(int offset, long l)\r\n28. StringBuffer insert(int offset, Object obj)\r\n29. StringBuffer insert(int offset, String str)\r\n\r\n以上的方法都是在当前StringBuffer对象中插入一个元素,在索引号offset处插入相应的值。\r\n30. int lastIndexOf(String str) :返回当前StringBuffer对象中,最后一个满足str子串的位置。\r\n31. int lastIndexOf(String str, int fromIndex) :从当前StringBuffer对象的fromIndex开始查找,返回最后一个满足str子串的位置。\r\n32. int length() :返回当前StringBuffer对象(字符缓冲区)中,字符串的长度。注意:此方法与capacity() 不同。\r\n33. StringBuffer replace(int start, int end, String str) :替换当前StringBuffer对象的字符串。从start开始,到end结束的位置替换成str。\r\n34. StringBuffer reverse() :将字符串翻转。\r\n\r\n\r\n\r\n\r\n\r\n\r\n
\r\n
StringBuffer sb = new StringBuffer(\"0123456789\");\r\nSystem.out.println( \"sb.reverse(): \" + sb.reverse() );
\r\n
\r\n结果为:sb.reverse(): 9876543210\r\n\r\n35. void setCharAt(int index, char ch) :设置索引号index的字符为ch。\r\n36. void setLength(int newLength) :重新设置字符串缓冲区中字符串的长度,如果newLength小于当前的字符串长度,将截去多余的字符。\r\n\r\n\r\n\r\n\r\n\r\n\r\n
\r\n
StringBuffer sb = new StringBuffer(\"0123456789\");\r\nsb.setLength(5);\r\nSystem.out.println( \"sb: \" + sb );
\r\n
\r\n结果为:sb: 01234\r\n\r\n37. String substring(int start) :取当前StringBuffer对象中,从start开始到结尾的子串。\r\n38. String substring(int start, int end) :取当前StringBuffer对象中,从start开始到end的子串。\r\n39. String toString() :将当前StringBuffer对象转换成String对象。\r\n\r\nString和StringBuffer的区别\r\n网上资料可以说是数不胜数,但是看到这篇文章,感觉里面做的小例子很有代表性,所以转一下,并自己做了一点总结。\r\n 1.两者的区别 \r\n在java中有3个类来负责字符的操作。\r\n1.Character 是进行单个字符操作的,\r\n2.String 对一串字符进行操作。不可变类。\r\n3.StringBuffer 也是对一串字符进行操作,但是可变类。\r\nString:\r\n是对象不是原始类型. \r\n为不可变对象,一旦被创建,就不能修改它的值.\r\n对于已经存在的String对象的修改都是重新创建一个新的对象,然后把新的值保存进去.\r\nString 是final类,即不能被继承.\r\nStringBuffer:\r\n是一个可变对象,当对他进行修改的时候不会像String那样重新建立对象\r\n它只能通过构造函数来建立,\r\nStringBuffer sb = new StringBuffer();\r\nnote:不能通过付值符号对他进行付值.\r\nsb = \"welcome to here!\";//error\r\n对象被建立以后,在内存中就会分配内存空间,并初始保存一个null.向StringBuffer\r\n中付值的时候可以通过它的append方法.\r\nsb.append(\"hello\");\r\n字符串连接操作中StringBuffer的效率要比String高:\r\nString str = new String(\"welcome to \");\r\nstr += \"here\";\r\n的处理步骤实际上是通过建立一个StringBuffer,然后调用append(),最后\r\n再将StringBuffer toSting();\r\n这样的话String的连接操作就比StringBuffer多出了一些附加操作,当然效率上要打折扣.\r\n并且由于String 对象是不可变对象,每次操作Sting 都会重新建立新的对象来保存新的值.\r\n这样原来的对象就没用了,就要被垃圾回收.这也是要影响性能的.\r\n看看以下代码:\r\n将26个英文字母重复加了5000次,\r\n\r\n\r\n\r\n\r\n\r\n\r\n
\r\n
  String tempstr = \"abcdefghijklmnopqrstuvwxyz\";\r\n         int times = 5000;\r\n         long lstart1 = System.currentTimeMillis();\r\n         String str = \"\";\r\n         for (int i = 0; i < times; i++) {\r\n             str += tempstr;\r\n         }\r\n         long lend1 = System.currentTimeMillis();\r\n         long time = (lend1 - lstart1);\r\n         System.out.println(time);
\r\n
\r\n可惜我的计算机不是超级计算机,得到的结果每次不一定一样一般为 46687左右。\r\n也就是46秒。\r\n我们再看看以下代码\r\n        \r\n\r\n\r\n\r\n\r\n\r\n\r\n
\r\n
 String tempstr = \"abcdefghijklmnopqrstuvwxyz\";\r\n         int times = 5000;\r\n         long lstart2 = System.currentTimeMillis();\r\n         StringBuffer sb = new StringBuffer();\r\n         for (int i = 0; i < times; i++) {\r\n             sb.append(tempstr);\r\n         }\r\n         long lend2 = System.currentTimeMillis();\r\n         long time2 = (lend2 - lstart2);\r\n         System.out.println(time2);
\r\n
\r\n得到的结果为 16 有时还是 0 所以结论很明显,StringBuffer 的速度几乎是String 上万倍。当然这个数据不是很准确。因为循环的次数在100000次的时候,差异更大。不信你试试。 \r\n\r\n根据上面所说:\r\nstr += \"here\";\r\n的处理步骤实际上是通过建立一个StringBuffer,调用append(),最后\r\n再将StringBuffer toSting();\r\n所以str += \"here\";可以等同于\r\nStringBuffer sb = new StringBuffer(str);\r\nsb.append(\"here\");\r\nstr = sb.toString();\r\n所以上面直接利用\"+\"来连接String的代码可以基本等同于以下代码\r\n\r\n\r\n\r\n\r\n\r\n\r\n
\r\n
  String tempstr = \"abcdefghijklmnopqrstuvwxyz\";\r\n         int times = 5000;\r\n         long lstart2 = System.currentTimeMillis();\r\n         String str = \"\";\r\n         for (int i = 0; i < times; i++) {\r\n             StringBuffer sb = new StringBuffer(str);\r\n             sb.append(tempstr);\r\n             str = sb.toString();\r\n         }\r\n         long lend2 = System.currentTimeMillis();\r\n         long time2 = (lend2 - lstart2);\r\n         System.out.println(time2);
\r\n
\r\n平均执行时间为46922左右,也就是46秒。\r\n2 StringBuffer可变与String不可变的真正原因 \r\n      String和StringBuffer都是final类,他们生成的对象在堆中都是不可变的,在他们内部都是靠属性char数组实现的, \r\n那为什么StringBuffer可以在对象中追加字符串呢?呵呵,因为String中的char数组是final的,也就是常量,是不可改变的,而StringBuffer继承自抽象类AbstractStringBuilder,他的内部实现靠他的父类完成,AbstractStringBuilder内的char数组是变量,可以用append追加 StringBuffer和StringBuilder都实现了AbstractStringBuilder抽象类,此抽象类实现Appendable接口因此可追加 (在JDK 6.0 API中StringBuilder和Stringbuff写着都继承自Object 而且在他的API中找不到AbstractStringBuilder类)\r\n3 到底该怎么简洁的回答 \r\nStringBuffer 支持多线程,也就是说StringBuffer是线程安全的。在连接字符串时直接用:Append(\"string\")就行,它的容量比较大,可以包含整篇文章。\r\nString不支持线程,所以它不安全,虽然在连接字符串时可用\"+\",但需要注意的是每\"+\"一次的同时就会在内存(堆)中增加一个空间地址。相对而言,你加的多了,就会使JVM出现内存溢出等错误。 \r\n\r\n如果在面试的时候出现这种题:你直接说:StringBuffer是线程安全的,String 则不是。就行了。\r\n总结: 如果在程序中需要对字符串进行频繁的修改连接操作的话.使用StringBuffer性能会更高。\r\n\r\n
\r\n ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2804, 'c-error-error-c2731-winmain-cannot-overload-function', 'C++ 错误提示error C2731:“WinMain”: 无法重载函数', '2012-11-15 16:23:26', '2019-03-25 21:29:22', '
\r\n 错误代码:
\r\n int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow )
\r\n
\r\n
\r\n 照抄下来,在VS2008或VS2010编译的时候总会说error C2731: “WinMain”: 无法重载函数。
\r\n
\r\n 其实因为WinMain函数的原始定义中lpCmdLine的类型是char *,但在中文系统的环境下因为启用了Unicode支持,LPTSTR代表的是WCHAR *。所以上述函数我们就应该这样来写:
\r\n
\r\n 修改后代码:
\r\n
\r\n int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow )
\r\n
\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2805, 'use-datagrid-in-vb6', 'VB6中DataGrid的使用', '2012-11-14 11:51:44', '2019-03-25 21:29:22', '      概述:
\r\n      DataGrid 控 件是一种类似于电子数据表的绑定控件,可以显示一系列行和列来表示 Recordset 对象的记录和字段。可以使用 DataGrid 来创建一个允许最终用户阅读和写入到绝大多数数据库的应用程序。DataGrid 控件可以在设计时快速进行配置,只需少量代码或无需代码。当在设计时设置了 DataGrid 控件的 DataSource 属性后,就会用数据源的记录集来自动填充该控件,以及自动设置该控件的列标头。然后您就可以编辑该网格的列;删除、重新安排、添加列标头、或者调整任意一列的宽度。

\r\n     在运行时,可以在程序中切换 DataSource 来察看不同的表,或者可以修改当前数据库 的查询,以返回一个不同的记录集合。
\r\n      注意:DataGrid 控件与 Visual Basic 5.0中的 DBGrid 是代码兼容的,除了一个例外:DataGrid 控件不支持 DBGrid 的“解除绑定模式”概念。DBGrid 控件包括在 Visual Basic 的 Tools 目录中。
\r\n      可能的用法:
\r\n      查看和编辑在远程或本地数据库中的数据。
\r\n      与另一个数据绑定的控件(诸如 DataList 控件)联合使用,使用 DataGrid控件来显示一个表的记录,这个表通过一个公共字段链接到由第二个数据绑定控件所显示的表。
\r\n      使用 DataGrid 控件的设计时特性
\r\n      可以不编写任何代码,只通过使用 DataGrid 控件的设计时特性来创建一个数据库应用程序。下面的说明概要地说明了在实现 DataGrid 控件的典型应用时的一般步骤。
\r\n      实现一个 DataGrid 控件
\r\n      首先,如果工具箱没有DataGrid空间,则需要引入,具体方法是:点击菜单项工程->部件,找到Microsoft ADO Data ControlMicrosoft DataGrid Control。勾上,并点击应用,然后关闭,这时,DataGrid控件和ADODC控件就会出现在工具箱了。

\r\n      1. 在窗体上放置一个ADODC控件,并将其 ConnectionString 属性设置为数据源。
\r\n      2. 在这个ADODC控件的RecordSource 属性中输入一条将返回一个记录集的 SQL 语句。例如,select Freq as 班次,StartTime as 发车时间,Start as 起点站,Stop as 终点站,TravelTime as 行车时间,RatedAmount as 额定数量,Ordered as 已订票人数,NoDisplay as 发车状态 from FreqInfo
\r\n      4. 在窗体上放置一个 DataGrid 控件,并将其 DataSource 属性设置为这个ADODC控件的名称。
\r\n      4. 右键单击该 DataGrid 控件,然后单击“检索字段”。
\r\n      5. 右键单击该 DataGrid 控件,然后单击“编辑”。
\r\n      6. 重新设置该网格的大小、删除或添加网格的列。
\r\n      7. 右键单击该 DataGrid 控件,然后单击“属性”。
\r\n      8. 使用“属性页”对话框来设置该控件的适当的属性,将该网格配置为所需的外观和行为。
\r\n      在运行时更改显示的数据
\r\n      在创建了一个使用设计时特性的网格后,也可以在运行时动态地更改该网格的数据源。下面介绍实现这一功能的通常方法。
\r\n      更改 DataSource 的RecordSource
\r\n      更改所显示的数据的最通常方法是改变该 DataSource 的查询。例如,如果DataGrid 控件使用一个ADO Data控件作为其 DataSource,则重写RecordSource和刷新该ADO Data 控件都将改变所显示的数据。
\r\n      更改 DataSource
\r\n      在 运行时,可以将 DataSource 属性重新设置为一个不同的数据源。例如,您可能具有若干个ADODC控件,每个控件连接不同的数据库, 或设置为不同的RecordSource属性。可以简单地将DataSource 从一个ADODC控件重新设置为另一 个ADODC控件。
\r\n      重新绑定DataSource
\r\n      当将DataGrid 控件用于一个远程数据库,诸如 SQLServer 时,可以改变表的结构。例如,可以给这个表添加一个字段。在这种情形下,可以 调用Rebind 方法根据新的结构来重新创建该网格。注意,如果已经在设计时改变了这个列的布局,DataGrid 控件将会试图重新创建当前的布局, 包括任何空的列。不过,通过首先调用 ClearFields 方法,可以强制该网格重新设置所有的列。
\r\n      从DataGrid 返回值
\r\n      在DataGrid 被连接到一个数据库后,可能想要监视用户单击了哪一个单元。可以使用 RowColChange 事件——而不是 Click 事件。如下所示:
\r\nPrivate Sub DataGrid1_RowColChange(LastRow As Variant, ByVal LastCol As Integer)
\r\n' 显示用户所单击的单元的文字、行和列的信息。
\r\nDebug.Print DataGrid1.Text; DataGrid1.Row; DataGrid1.Col
\r\nEnd Sub

\r\n      使用CellText和CellValue方法
\r\n      当一个列使用 NumberFormat 属性设置格式后,CellText 和 CellValue 属性是很有用的。NumberFormat 属性不必更改实际的数据格式就可以更改任何包含数字的列的格式。例如,给定一个网格,其中包含一个名为 ProductID的、包含整数的列。下面的代码将 使 DataGrid 以"P-0000" 的格式来显示数据。换句话说,尽管在 ProductID 字段中所包含的实际数值为 "3",但该网格所显 示的值将是 "P-0003"。
\r\nPrivate Sub Form_Load()
\r\nDataGrid1.Columns("ProductID").NumberFormat = "P-0000"
\r\nEnd Sub

\r\n      要返回数据库中所包含的实际值,应使用 CellValue 方法,如下所示:
\r\nPrivate Sub DataGrid1_RowColChange(LastRow As Variant, ByVal LastCol As Integer)
\r\nDebug.Print _
\r\nDataGrid1.Columns("ProductID").CellValue(DataGrid1.Bookmark)

\r\nEnd Sub
\r\n      注意:上面所用的CellValue和下面所用的CellText值,都需要将Bookmark 属性作为一个参数,功能才正确。
\r\n      相反地,如果要返回该字段的格式化的值,应使用 CellText 方法:
\r\nPrivate Sub DataGrid1_RowColChange(LastRow As Variant, ByVal LastCol As Integer)
\r\nDebug.Print _
\r\nDataGrid1.Columns("ProductID").CellText(DataGrid1.Bookmark)

\r\nEnd Sub
\r\n      注意:上面的CellText 方法等价于使用 DataGrid 控件的Text 属性。
\r\n
\r\n      使用DataGrid 和ADODC控件创建一个简单的数据库应用程序
\r\n      只使用一个 DataGrid 和一个ADODC控件,可以创建一个允许最终用户阅读和写入记录集的数据库应用程序。
\r\n      使用 ADO 数据控件来创建一个简单的数据库应用程序步骤如下:
\r\n      1. 在Visual Basic中创建一个新的标准的 EXE 工程。如果 DataGrid 控件不在“工具箱”中,则用右键单击“工具箱”,然后使用“部件”对话框来添加控件。同时也载入 ADO 控件。
\r\n3. 在空窗体上各放置控件的一个实例(DataGrid控件和ADODC控件)。
\r\n4. 将 ADODC控件的ConnectionString 属性设置为数据源。
\r\n5. 设置 ADODC控件的 RecordSource 属性。在“属性”窗口中,单击“记录源”并输入一条 SQL 语句来填充 DataGrid控件。在本例中,输入“Select * From Products”。
\r\n6. 将 DataGrid 控 件的 DataSource 属性设置为这个ADODC控件。
\r\n7. 按 F5 键运行这个工程。
\r\n

\r\n       使用列
\r\n       通过更改 DataSource 属性,可以动态地更改在 DataGrid 控件中显示的数据。例如,可以显示同一个数据库的不同表。如果这样做,则 DataGrid 控件将只根据默认的属性显示数据。
\r\n       添加、删除或隐藏列
\r\n       通过使用 Columns 集合和 Column 对象的属性和方法,可以在程序中添加、删除或隐藏列。
\r\n       添加和删除一列
\r\n       要在运行时添加一列,可以使用 Add 方法。如果首先声明一个变量,并将新对象赋给该变量,就可以用简明的代码设置各种属性。
\r\n Private Sub AddColumn()
\r\n ' 在最右边的位置添加一列。然后设置其 Visible、Width、
\r\n ' Caption以及 Alignment 属性。DataField 属性则指定
\r\n ' 该列将绑定到哪一个字段。
\r\n Dim c As Column
\r\n Set c = DataGrid1.Columns.Add(DataGrid1.Columns.Count)
\r\n With c
\r\n .Visible = True
\r\n .Width = 1000
\r\n .Caption = "我的新列"
\r\n .DataField = Adodc1.Recordset.Fields("ProductName").Name
\r\n .Alignment = dbgRight
\r\n End With
\r\n End Sub

\r\n       可以使用方法来删除任意一列。请确保使用 ColIndex 参数来指定要删除的列。下面的代码将删除被单击的列。
\r\n Private Sub DataGrid1_HeadClick(ByVal ColIndex As Integer)
\r\n DataGrid1.Columns.Remove ColIndex

\r\n End Sub
\r\n       隐藏一列
\r\n       通过将 Visible 属性设置为 False,可以隐藏任意一列。当想要限制用户可以查看或编辑的列时这一功能特别有用。下面的示例在 Columns 集合中循环,隐藏除少数列之外的所有列。
\r\n Private Sub HideColumns()
\r\n ' 使用 DataField 属性来判别正在测试的是哪一列。
\r\n ' 只显示三列:ProductName、UnitPrice以及
\r\n ' UnitsInStock。
\r\n Dim c As Column
\r\n For Each c In DataGrid1.Columns
\r\n Select Case c.DataField
\r\n Case "ProductName"
\r\n c.Visible = True
\r\n Case "UnitPrice"
\r\n c.Visible = True
\r\n Case "UnitsInStock"
\r\n c.Visible = True
\r\n c.Caption = "In Stock" ' 更改这个列的标头。
\r\n Case Else ' 隐藏其它所有的列。
\r\n c.Visible = False
\r\n End Select
\r\n Next c
\r\n End Sub

\r\n
\r\n       操作DataGrid视图
\r\n       一 个“拆分”的网格使最终用户对相同的数据可以拥有多个视图。例如,假设有一个由十个字段组成的大表。在这种情况下,在控件中察看的记录集将有十列宽,除非窗体非常宽,否则用户将无法同时看见所有列的内容。,而且,假设用户只对第一列和最后一列感兴趣(例如,第一列是名字,最后一列是电话号码)。为了能同时 看到在两端的列(不重新安排列的顺序),可以对网格进行拆分。
\r\n       创建一个Split 对象
\r\n       在设计时,可以创建一个拆分,具体步骤是:右键单击网格,单击“编辑”,再单击右键,然后单击“拆分”。通过右键单击该控件,并单击“属性”来显示“属性 页”对话框,可以编辑这个拆分。可以使用“拆分”选项卡来自定义拆分。要删除一个拆分,右键单击该拆分,并单击“删除”。
\r\n       在运行时,最终用户也可以通过单击位于这个网格控件的左下边的右边的选项卡,以手工方式来拆分该网格(除非不允许这个操作)。
\r\n       默认情况下,DataGrid 控件包含一个 Split 对象。防止最终用户添加拆分的代码为:
\r\n DataGrid1.Splits(0).AllowSizing = False
\r\n       在程序中添加和删除拆分
\r\n       DataGrid 控件包含一个 Split 对象的集合。要在程序中添加拆分,可以使用 Add 方法,如下所示:
\r\n DataGrid1.Splits.Add 1
\r\n       注意 Add 方法需要新的拆分索引作为其参数。要添加一个拆分,应将这个索引参数设置为 Splits 集合的 Count 属性值。
\r\n       使用 Split 集合的 Add 方法,可以在程序中按照实际需要添加拆分。由于添加多于两个以上的拆分将使网格很难使用,可以使用该集合的 Count 属性来限制拆分的数目。
\r\n If DataGrid1.Splits.Count < 3 Then ' 添加一个拆分。
\r\n DataGrid1.Splits.Add DataGrid1.Splits.Count
\r\n End If

\r\n       使拆分同步
\r\n       当拆分多于一个时,可能希望控制这些拆分如何滚动。例如,在一个具有三个拆分的网格中,可以决定只让第一个和第三个拆分同步,而让中间的拆分独立地滚动。要同步任何两个(或多个)拆分,只需将每个 Split 对象的 ScrollGroup 属性设置为同一个值。
\r\n ' 使第一个和第三个 Split 对象同步。
\r\n With DataGrid1
\r\n .Splits(0)
\r\n .ScrollGroup = 1
\r\n .Splits(1).ScrollGroup = 2
\r\n .Splits(2).ScrollGroup = 1
\r\n End With

\r\n       通过设置 Scrollbars 属性,使同步的拆分组只显示一个滚卷条,从而进一步自定义拆分的外观。
\r\n       控制Tab 键和箭头键的行为
\r\n       使用 WrapCellPointer、TabAcrossSplits以及 TabAction 属性,可以决定当最终用户按下 tab 键或箭头键时网格的行为。
\r\n       在这三个属性中,TabAction 属性级别最高,它决定 WrapCellPointer 和TabAcrossSplits 这两个属性是否能生效。 TabAction 有三个设置值:ControlNavigation、Column Navigation 和 Grid Navigation。 当该属性设置为 ControlNavigation 时,按 Tab 键根据 TabIndex 将焦点切换到下一个控件。这一设置优先 于 WrapCellPointer 和TabAcrossSplits。
\r\n       WrapCellPointer 属 性决定在任何单个的拆分中 tab 键和箭头键的行为。如果该属性设置为 True,且当前单元位于最后一列,这时最终用户按 tab 键则使第一列的下 一行变成当前的单元。不过,如果当前单元位于最后一行的最后一列时,这时就没有地方可以“换行”。
\r\n       TabAcrossSplits 属性决定当网格中存在两个或多个拆分时 tab 和箭头键的行为。如果该属性设置为 True,且当前单元位于任何一个拆分的最后一列,则按Tab或箭头键将使当前单元“跳” 到下一个拆分的第一列。当前单元仍保持相同的行位置。
\r\n       注意:如果 WrapCellPointer 和 TabAcrossSplits 属性都设置为 True,则只有当前单元位于最后一个拆分的最后一列时才会换行。这时当前单元将换到第一个拆分的第一列中的下一行。
\r\n    
\r\n       自定义列集合

\r\n       每一个 Split 对象都有一个 Columns 属性,允许用户来操作一个 Column对象的集合。通过这样做,可以更改每个 Split 对象的外 观。例如,可以用一个拆分包含显示姓氏字段和名字字段的两个列,而第二个拆分则显示电话字段和地址字段。要实现这一目标,需要将其它的每一列 的 Visible 属性设置为 False,如下所示:
\r\n ' 枚举 Columns 集合,对每一个 Column 对象的 DataField 属性
\r\n ' 进行测试。如果测试失败,则隐藏这一列。
\r\n Dim i As Integer
\r\n ' 隐藏除 ProductName 列之外的所有列。
\r\n For i = 0 To DataGrid1.Splits(0).Columns.Count - 1
\r\n If DataGrid1.Splits(0).Columns(i).DataField <> "ProductName" Then
\r\n DataGrid1.Splits(0).Columns(i).Visible = False
\r\n End If
\r\n Next i

\r\n ' 隐藏除 UnitPrice 列之外的所有列。
\r\n For i = 0 To DataGrid1.Splits(0).Columns.Count - 1
\r\n If DataGrid1.Splits(1).Columns(i).DataField <> "UnitPrice" Then
\r\n DataGrid1.Splits(1).Columns(i).Visible = False
\r\n End If

\r\n Next I
\r\n       使用 Bookmarks 和 SelBookmarks 跟踪记录
\r\n       Bookmarks 和 SelBookmarks 提 供了标记记录的一种手段。当编写应用程序中的特定功能(诸如允许最终用户手工地选择多个不相邻的记录,进行所选记录的大批更新)时,这就很有必要。在这些 情形中,需要标记哪些记录已被选择,因此可以使用 SelBookmarks 集合及其属性。
\r\n       有两个函数,分别是 CellText 和 CellValue 方法,需要标记才能正确执行。
\r\n       标记用户的选择
\r\n       SelBookmarks 集合包含所有选定的记录的书签。当最终用户手工选择记录时(即在单击时按住 CTRL 键),每一个选定的记录的书签都会加入到该集合中。使用标准的循环,用户可以知道已经选定了什么,也可以保存书签(因为可能需要恢复某个值),以及执行操作:
\r\n Dim i as Integer ' 计数器
\r\n Dim intCount As Integer
\r\n intCount = DataGrid1.SelBookmarks.Count - 1
\r\n ReDim arrSelBK(intCount) ' 声明用于保存书签的数组。
\r\n For i = 0 To intCount
\r\n ArrSelBK(i) = DataGrid1.SelBookmarks(i)
\r\n ' 在此处执行操作。如果该操作必须被
\r\n ' 取消,则退出该循环,然后使用该数
\r\n ' 组来取消这些更改。
\r\n Next i

\r\n
\r\n       通过在程序中添加到 SelBookmarks 集合来选择记录
\r\n       通过将记录添加到这个集合,也可以在程序中选定记录。例如,可能有一个显示指定的客户所有订货的网格。如果要高亮显示该客户花费超过 $100的所有记录,则对记录进行过滤,并将结果书签添加到 SelBookmarks 集合。
\r\n Dim rs As Recordset
\r\n Set rs = Adodc1.Recordset
\r\n While Not rs.EOF
\r\n If rs!SupplierID = 12 Then
\r\n DataGrid1.SelBookmarks.Add rs.Bookmark
\r\n End If
\r\n rs.MoveNext
\r\n Wend

\r\n       显示计算结果字段
\r\n       假设在表中有一个名为 "Price" 的字段,并且想使用本地税率来计算表中每一项的税费。这就是一个计算结果字段,可以通过修改 DataSource 的查询来计算这个值,并把这个值返回给 DataGrid 控件。
\r\n       与类模块一起使用 DataGrid 控件
\r\n       如果想要访问以自定义格式或以 ODBC 驱动程序不直接支持的格式存放的数据,可以创建一个类来封装该数据。然后可以编写该类的自定义函数来检索这些数据。这样该类就变成了一种数据源,可以被任何数据使用者(如DataGrid 控件)使用。
\r\n       在这个类模块的Initialize 事件中,首先通过声明一个作为 New ADODB.Recordset的变量,来创建一 个 ADODB recordset 对象。在创建了这个 recordset 对象后,再添加字段,每个数据源中的每个字段都要加入。然后使用合适的数 据填充这个记录集。
\r\n       类模块有一个 GetDataMember 事件,只要当数据使用者(诸如 DataGrid 控件)需要数据时就产生该事件。在这个事件中,Data 参数被设置为在Initialize 事件中所创建的 recordset 对象。
\r\n       如果要使用这个类模块,应创建一个具有一个 DataGrid 控件的窗体。在该窗体的 Load 事件的代码中,将该控件的 DataSource 属性设置为这个类。
\r\n       注意:数据类模块在设计时是不可用的。例如,如果使用 DataGrid 控件,则当用户在“属性”窗口中单击“数据源”时,所有可用的数据源都会出现在一个下拉列表中。但其中不会有这个数据类模块,它只能在代码中设置。

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2806, 'vs-2008-crack-method', 'VS 2008破解方法', '2012-11-14 19:27:43', '2019-03-25 21:29:22', '
\r\n
\r\n  
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2807, 'c-sizeof-rule-and-its-trap-analysis', 'C++ sizeof使用规则及陷阱分析', '2012-11-13 22:06:13', '2019-03-25 21:29:22', '一、什么是sizeof
\r\n       首先看一下sizeof在msdn上的定义:
\r\n

\r\n       The sizeof keyword gives the amount of storage, in bytes, associated with a variable or a type (including aggregate types). This keyword returns a value of type size_t.

\r\n

\r\n       看到return这个字眼,是不是想到了函数?错了,sizeof不是一个函数,你见过给一个函数传参数,而不加括号的吗?sizeof可以,所以sizeof不是函数。网上有人说sizeof是一元操作符,但是我并不这么认为,因为sizeof更像一个特殊的宏,它是在编译阶段求值的。举个例子:

\r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\ncout<<sizeof(int)<<endl; // 32位机上int长度为4\r\ncout<<sizeof(1==2)<<endl; // == 操作符返回bool类型,相当于 cout<<sizeof(bool)<<endl;
\r\n
\r\n
\r\n \"\"
\r\n

\r\n        在编译阶段已经被翻译为:

\r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n  cout<<4<<endl;\r\n  cout<<1<<endl;
\r\n
\r\n
\r\n

\r\n        这里有个陷阱,看下面的程序:

\r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n int a = 0;\r\n cout<<sizeof(a=3)<<endl;\r\n cout<<a<<endl;
\r\n
\r\n
\r\n \"\"
\r\n

\r\n        输出为什么是4,0而不是期望中的4,3???就在于sizeof在编译阶段处理的特性。由于sizeof不能被编译成机器码,所以sizeof作用范围 内,也就是()里面的内容也不能被编译,而是被替换成类型。=操作符返回左操作数的类型,所以a=3相当于int,而代码也被替换为:

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n int a = 0;\r\n cout<<4<<endl;\r\n cout<<a<<endl;
\r\n
\r\n
\r\n   
\r\n       再如:
\r\n  
\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n    cout << sizeof("abcd") << endl;//5
\r\n
\r\n
\r\n

\r\n     \"\"
\r\n       "abcd"返回是字符串类型,所以,sizeof是不可能支持链式表达式的,这也是和一元操作符不一样的地方。

\r\n

\r\n       结论:不要把sizeof当成函数,也不要看作一元操作符,把他当成一个特殊的编译预处理。

\r\n

\r\n 二、sizeof的用法
\r\n        sizeof有两种用法:
\r\n     (1)sizeof(object) sizeof object 
\r\n       也就是对对象使用sizeof,也可以写成sizeof object 的形式。
例如:

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n   cout<< sizeof(cout)<<endl;//80
\r\n
\r\n

\r\n     (2)sizeof(typename)
\r\n       也就是对类型使用sizeof,注意这种情况下写成sizeof typename是非法的。下面举几个例子说明一下:

\r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n  int i = 2;\r\n  cout<<sizeof(i)<<endl; // sizeof(object)的用法,合理\r\n  cout<<sizeof i<<endl; // sizeof object的用法,合理\r\n  cout<<sizeof 2<<endl; // 2被解析成int类型的object, sizeof object的用法,合理\r\n  cout<<sizeof(2)<<endl; // 2被解析成int类型的object, sizeof(object)的用法,合理\r\n  cout<<sizeof(int)<<endl;// sizeof(typename)的用法,合理\r\n  cout<<sizeof int<<endl; // 错误!对于操作符,一定要加()
\r\n
\r\n
\r\n

\r\n        可以看出,加()是永远正确的选择

\r\n

\r\n        结论:不论sizeof要对谁取值,最好都加上()。

\r\n

\r\n
\r\n 三、基本数据类型的sizeof
\r\n       (1)C++内置数据类型

\r\n

\r\n        32位C++中的基本数据类型,

\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n  \r\n bool\r\n char\r\n short int(short)\r\n int\r\n long int(long)\r\n float\r\n double\r\n long double
\r\n sizeof\r\n 1\r\n 1\r\n 2\r\n 4\r\n 4\r\n 4\r\n 8\r\n 10
\r\n
\r\nchar,short int(short),int,long int(long),float,double, long double大小分别是:1,2,4,4,4,8, 10。\r\n

\r\n        考虑下面的代码:

\r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n    cout<<(sizeof(unsigned int) == sizeof(int))<<endl; // 相等,输出 1
\r\n
\r\n
\r\n

\r\n     unsigned影响的只是最高位bit的意义,数据长度不会被改变的。

\r\n

\r\n     结论:unsigned不能影响sizeof的取值。

\r\n

\r\n (2)自定义数据类型

\r\n

\r\n        typedef可以用来定义C++自定义类型。考虑下面的问题:

\r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n  typedef short WORD;\r\n  typedef long DWORD;\r\n  cout<<(sizeof(short) == sizeof(WORD))<<endl; // 相等,输出1\r\n  cout<<(sizeof(long) == sizeof(DWORD))<<endl; // 相等,输出1
\r\n
\r\n
\r\n

\r\n     结论:自定义类型的sizeof取值等同于它的类型原形。

\r\n

\r\n (3)函数类型

\r\n

\r\n        考虑下面的问题:

\r\n
\r\n   \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n    int f1(){return 0;};\r\n    double f2(){return 0.0;}\r\n    void f3(){}\r\n\r\n\r\n    cout<<sizeof(f1())<<endl; // f1()返回值为int,因此被认为是int\r\n    cout<<sizeof(f2())<<endl; // f2()返回值为double,因此被认为是double\r\n    cout<<sizeof(f3())<<endl; // 错误!无法对void类型使用sizeof\r\n    cout<<sizeof(f1)<<endl;  // 错误!无法对函数指针使用sizeof   \r\n    cout<<sizeof *f2<<endl;  // *f2,和f2()等价,因为可以看作object,所以括号不是必要的。被认为是double
\r\n
\r\n
\r\n

\r\n         结论:对函数使用sizeof,在编译阶段会被函数返回值的类型取代。

\r\n

\r\n  (4)、指针问题

\r\n

\r\n         考虑下面问题:

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n cout<<sizeof(string*)<<endl; // 4\r\n cout<<sizeof(int*)<<endl; // 4\r\n cout<<sizof(char****)<<endl; // 4
\r\n
\r\n

\r\n        可以看到,不管是什么类型的指针,大小都是4的,因为指针就是32位的物理地址。

\r\n

\r\n        结论:只要是指针,大小就是4。(64位机上要变成8也不一定)。

\r\n

\r\n        C++中的指针表示实际内存的地址。和C不一样的是,C++中取消了模式之分,也就是不再有small,middle,big,取而代之的是统一的 flat。flat模式采用32位实地址寻址,而不再是c中的 segment:offset模式。举个例子,假如有一个指向地址 f000:8888的指针,如果是C类型则是8888(16位, 只存储位移,省略段),far类型的C指针是f0008888(32位,高位保留段地址,地位保留位移),C++类型的指针是f8888(32位,相当于 段地址*16 + 位移,但寻址范围要更大)。

\r\n

\r\n  (5)、数组问题

\r\n

\r\n        考虑下面问题:

\r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n   char a[] = "abcdef";\r\n   char b[] = {'a', 'b', 'c', 'd', 'e', 'f'};\r\n   int c[20] = {3, 4};\r\n   char d[2][3] = {"aa", "bb"};\r\n\r\n   cout<<sizeof(a)<<endl; // 7, 表示字符串\r\n   cout<<sizeof(b)<<endl; // 6, 仅表示字符数组\r\n   cout<<sizeof(c)<<endl; // 80\r\n   cout<<sizeof(d)<<endl; // 6\r\n   cout << sizeof(*a) << endl;//1\r\n   cout << sizeof(*b) << endl;//1\r\n   cout << sizeof(*c) << endl;//4\r\n   cout << sizeof(*d) << endl;//3\r\n
\r\n
\r\n
\r\n       特别如果字符数组表示字符串的话,数组末自动插入的' ',在sizeof时不能遗漏
\r\n

\r\n       数组a的大小在定义时未指定,编译时给它分配的空间是按照初始化的值确定的,也就是7。c是多维数组,占用的空间大小是各维数的乘积,也就是6。可以看出,数组的大小就是他在编译时被分配的空间,也就是各维数的乘积*数组元素的大小。

\r\n

\r\n     结论:数组的大小是各维数的乘积*数组元素的大小。

\r\n

\r\n     这里有一个陷阱:

\r\n
\r\n 1  int *d = new int[10];
\r\n 2 
\r\n 3  cout<<sizeof(d)<<endl; // 4
\r\n 4
\r\n

\r\n     d是我们常说的动态数组,但是他实质上还是一个指针,所以sizeof(d)的值是4。

\r\n

\r\n     再分析下面的多维数组问题:

\r\n
\r\n 1  double* (*a)[3][6];
\r\n 2  
\r\n 3  cout<<sizeof(a)<<endl;  // 4
\r\n 4  cout<<sizeof(*a)<<endl;  // 72
\r\n 5  cout<<sizeof(**a)<<endl; // 24
\r\n 6  cout<<sizeof(***a)<<endl; // 4
\r\n 7  cout<<sizeof(****a)<<endl; // 8
\r\n

\r\n    很费解的多维数组定义,改用typedef定义如下:

\r\n
\r\n 1    typedef (double *) ArrType [3][6];
\r\n 2    ArrType * a;
\r\n

\r\n    现在是不是很清晰了?(关于typedef用法的探讨,请见文章)

\r\n
\r\n 1    typedef (double *) ArrType [3][6];
\r\n 2    ArrType * a;
\r\n 3
\r\n 4    cout << sizeof(a) << endl;//4
\r\n 5    cout << sizeof(*a) << endl;// double * [3][6] : 3*6*sizeof(double *) = 72 
\r\n 6    cout << sizeof(**a) << endl;// double * [6] :  6*sizeof(double *) = 24
\r\n 7    cout << sizeof(***a) << endl;// sizeof(double *) = 4
\r\n 8    cout << sizeof(****a) << endl;// sizeof(double) = 8
\r\n

\r\n
\r\n     a是一个很奇怪的定义,他表示一个指向 double*[3][6]类型数组的指针,此3×6数组中存储的是指向double的指针。既然是指针,所以sizeof(a)就是4

\r\n

\r\n     既然a是指向double*[3][6]类型的指针:
\r\n    *a就表示一个double*[3][6]的多维数组类型,因此sizeof(*a)=3*6*sizeof(double*)=72。
\r\n    **a表示一个double*[6]类型的数组,所以sizeof(**a)=6*sizeof(double*)=24。
\r\n    ***a就表示其中的第一个元素,也就是double*了,所以sizeof(***a)=4。
\r\n    ****a,就是一个double了,所以sizeof(****a)=sizeof(double)=8

\r\n

\r\n
\r\n (6)、向函数传递数组的问题。

\r\n

\r\n     考虑下面的问题:

\r\n
\r\n  1 #include <iostream>
\r\n  2 using namespace std;
\r\n  3 
\r\n  4 int Sum(int i[])
\r\n  5 {
\r\n  6  int sumofi = 0;
\r\n  7  for (int j = 0; j < sizeof(i)/sizeof(int); j++) //实际上,sizeof(i) = 4
\r\n  8  {
\r\n  9   sumofi += i[j];
\r\n 10  }
\r\n 11  return sumofi;
\r\n 12 }
\r\n 13 
\r\n 14 int main()
\r\n 15 {
\r\n 16  int allAges[6] = {21, 22, 22, 19, 34, 12};
\r\n 17  cout<<Sum(allAges)<<endl;
\r\n 18  system("pause");
\r\n 19  return 0;
\r\n 20 }
\r\n 21 
\r\n 22
\r\n

\r\n
\r\n     Sum的本意是用sizeof得到数组的大小,然后求和。但是实际上,传入自函数Sum的,只是一个int 类型的指针,所以sizeof(i)=4,而不是24,所以会产生错误的结果。解决这个问题的方法使是用指针或者引用。

\r\n

\r\n     使用指针的情况:

\r\n
\r\n  1 int Sum(int (*i)[6])
\r\n  2 {
\r\n  3  int sumofi = 0;
\r\n  4  for (int j = 0; j < sizeof(*i)/sizeof(int); j++) //sizeof(*i) = 24
\r\n  5  {
\r\n  6   sumofi += (*i)[j];
\r\n  7  }
\r\n  8  return sumofi;
\r\n  9 }
\r\n 10 
\r\n 11 int main()
\r\n 12 {
\r\n 13  int allAges[] = {21, 22, 22, 19, 34, 12};
\r\n 14  cout<<Sum(&allAges)<<endl;
\r\n 15  system("pause");
\r\n 16  return 0;
\r\n 17 }
\r\n 18 
\r\n 19
\r\n

\r\n     在这个Sum里,i是一个指向i[6]类型的指针,注意,这里不能用int Sum(int (*i)[])声明函数,而是必须指明要传入的数组的大小,不然sizeof(*i)无法计算。但是在这种情况下,再通过sizeof来计算数组大小已经 没有意义了,因为此时大小是指定为6的。
\r\n
\r\n 使用引用的情况和指针相似:

\r\n
\r\n  1 int Sum(int (&i)[6])
\r\n  2 {
\r\n  3  int sumofi = 0;
\r\n  4  for (int j = 0; j < sizeof(i)/sizeof(int); j++)
\r\n  5  {
\r\n  6   sumofi += i[j];
\r\n  7  }
\r\n  8  return sumofi;
\r\n  9 }
\r\n 10 
\r\n 11 int main()
\r\n 12 {
\r\n 13  int allAges[] = {21, 22, 22, 19, 34, 12};
\r\n 14  cout<<Sum(allAges)<<endl;
\r\n 15  system("pause");
\r\n 16  return 0;
\r\n 17 }
\r\n 18
\r\n

\r\n
\r\n     这种情况下sizeof的计算同样无意义,所以用数组做参数,而且需要遍历的时候,函数应该有一个参数来说明数组的大小,而数组的大小在数组定义的作用域内通过sizeof求值。因此上面的函数正确形式应该是:

\r\n
\r\n  1 #include <iostream>
\r\n  2 using namespace std;
\r\n  3 
\r\n  4 int Sum(int *i, unsigned int n)
\r\n  5 {
\r\n  6  int sumofi = 0;
\r\n  7  for (int j = 0; j < n; j++)
\r\n  8  {
\r\n  9   sumofi += i[j];
\r\n 10  }
\r\n 11  return sumofi;
\r\n 12 }
\r\n 13 
\r\n 14 int main()
\r\n 15 {
\r\n 16  int allAges[] = {21, 22, 22, 19, 34, 12};
\r\n 17  cout<<Sum(i, sizeof(allAges)/sizeof(int))<<endl;
\r\n 18  system("pause");
\r\n 19  return 0;
\r\n 20 }
\r\n 21 
\r\n 22
\r\n

\r\n (7)、C风格字符串与C++风格字符串类(String)的sizeof和strlen

\r\n

\r\n     考虑下面的问题:

\r\n
\r\n  1 #include <string>
\r\n  2 using namespace std;
\r\n  3 
\r\n  4  char a[] = "abcdef";
\r\n  5  char b[20] = "abcdef";
\r\n  6  string s = "abcdef";
\r\n  7  
\r\n  8  cout<<strlen(a)<<endl;  // 6,字符串长度
\r\n  9  cout<<sizeof(a)<<endl;  // 7,字符串容量
\r\n 10  cout<<strlen(b)<<endl;  // 6,字符串长度
\r\n 11  cout<<sizeof(b)<<endl;  // 20,字符串容量
\r\n 12  //cout<<strlen(s)<<endl;  // 错误!s不是一个字符指针。
\r\n 13  cout<<sizeof(s)<<endl;  // 16, 这里不代表字符串的长度,而是string类的大小
\r\n 14 
\r\n 15  a[1] = ' ';
\r\n 16  cout<<strlen(a)<<endl;  // 1
\r\n 17  cout<<sizeof(a)<<endl;  // 7,sizeof是恒定的,因为是前面已经固定分配过7个单元,虽然现在字符串变为空串
\r\n 18
\r\n

\r\n
\r\n       记住:String是class类型。(关于class类型的sizeof请参见第五节)
\r\n
\r\n     strlen是寻找从指定地址开始,到出现的第一个0之间的字符个数,他是在运行阶段执行的,而sizeof是得到数据的大小,在这里是得到字符串的容 量。所以对同一个对象而言,sizeof的值是恒定的。string是C++类型的字符串,他是一个类,所以sizeof(s)表示的并不是字符串的长 度,而是类string的大小。strlen(s)根本就是错误的,因为strlen的参数是一个字符指针,如果想用strlen得到s字符串的长度,应 该使用sizeof(s.c_str()),因为string的成员函数c_str()返回的是字符串的首地址。实际上,string类提供了自己的成员 函数来得到字符串的容量和长度,分别是Capacity()和Length()。string封装了常用了字符串操作,所以在C++开发过程中,最好使用 string代替C类型的字符串。
\r\n
\r\n    STL中的String类:
\r\n    string的sizeof和平台相关 的,string类最简单的可以近似认为是包含两个数据成员:char *指针成员( 表示字符数组)和 int成员(表示字符串长度)。但是事实上并不是这样定义的,可能还有其他数据成员,如编译器插入指针vptr等。因此根据不同的实现,可以查看 String类的定义中如何定义。比如在我现在机器上,sizeof(string) = 16

\r\n

\r\n 四、复杂数据类型中sizeof及其数据对齐问题
\r\n
\r\n (1)、union的sizeof问题与cpu的对界

\r\n

\r\n     考虑下面问题:(默认对齐方式)

\r\n
\r\n  1  union u //8对齐
\r\n  2  {
\r\n  3   double a;
\r\n  4   int b;
\r\n  5  };
\r\n  6 
\r\n  7  union u2 //4对齐
\r\n  8  {
\r\n  9   char a[13];
\r\n 10   int b;
\r\n 11  };
\r\n 12 
\r\n 13  union u3 //1对齐
\r\n 14  {
\r\n 15   char a[13];
\r\n 16   char b;
\r\n 17  };
\r\n 18 
\r\n 19  cout<<sizeof(u)<<endl;  // 8
\r\n 20  cout<<sizeof(u2)<<endl;  // 16
\r\n 21  cout<<sizeof(u3)<<endl;  // 13
\r\n 22
\r\n

\r\n  

\r\n

\r\n     都知道union的大小取决于它所有的成员中,占用空间最大的一个成员的大小。所以对于u来说,大小就是最大的double类型成员a了,所以 sizeof(u)=sizeof(double)=8。但是对于u2和u3,最大的空间都是char[13]类型的数组,为什么u3的大小是13,而 u2是16呢?关键在于u2中的成员int b。由于int类型成员的存在,使u2的对齐方式变成4(4字节对齐),也就是说,u2的大小必须在4的对界上,所以占用的空间变成了16(最接近13的 对界)。

\r\n

\r\n     结论:复合数据类型,如union,struct,class的对齐方式为成员中对齐方式最大的成员的对齐方式。

\r\n

\r\n    编译器对界:
\r\n     首先解释下CPU对界问题,32的C++采用8位对界来提高运行速度,所以编译器会尽量把数据放在它的对界上以提高内存命中率。
\r\n    通过程序可以改变编译器对界,使用#pragma pack(x)宏可以改变编译器的对界方式,默认是8。
\r\n     编译器对界与实际对界判决原则:
\r\n    C++固有类型的对界取编译器对界方式(默认或指定)与自身大小中较小的一个.
\r\n    例如,指定编译器按2对界,int类型的大小是4,则int的对界为2和4中较小的2。
\r\n    在默认的对界方式下,因为几乎所有的数据类型都不大于默认的对界方式8(除了long double),所以所有的固有类型的对界方式可以认为就是类型自身的大小。
\r\n
\r\n 更改一下上面的程序:

\r\n
\r\n  1 #pragma pack(2)
\r\n  2  union u2
\r\n  3  {
\r\n  4   char a[13];
\r\n  5   int b;
\r\n  6  };
\r\n  7 
\r\n  8  union u3
\r\n  9  {
\r\n 10   char a[13];
\r\n 11   char b;
\r\n 12  };
\r\n 13  #pragma pack(8)
\r\n 14 
\r\n 15  cout<<sizeof(u2)<<endl;  // 14
\r\n 16  cout<<sizeof(u3)<<endl;  // 13
\r\n 17 
\r\n 18     
\r\n 19
\r\n

\r\n
\r\n  由于手动更改对界方式为2,所以int的对界也变成了2,u2的对界取成员中最大的对界,也是2了,所以此时sizeof(u2)=14。

\r\n

\r\n     结论:C++固有类型的对界取编译器对界方式与自身大小中较小的一个。

\r\n

\r\n
\r\n (2)、struct的sizeof问题

\r\n

\r\n     因为对齐问题使结构体的sizeof变得比较复杂,看下面的例子:(默认对齐方式下)

\r\n
\r\n  1  struct s1
\r\n  2  {
\r\n  3   char a;
\r\n  4   double b;
\r\n  5   int c;
\r\n  6   char d; 
\r\n  7  };
\r\n  8 
\r\n  9  struct s2
\r\n 10  {
\r\n 11   char a;
\r\n 12   char d;
\r\n 13   int c;
\r\n 14   double b;
\r\n 15  };
\r\n 16 
\r\n 17  cout<<sizeof(s1)<<endl; // 24
\r\n 18  cout<<sizeof(s2)<<endl; // 16
\r\n 19
\r\n

\r\n
\r\n    
\r\n     这里数据对齐与struct中元素的顺序相关. 上面例子中只是改变了struct中成员的定义顺序
\r\n
\r\n     同样是两个char类型,一个int类型,一个double类型,但是因为对界问题,导致他们的大小不同。
\r\n    计算结构体大小可以采用元素摆放法,我举例子说明一下:首先,CPU判断结构体的对界,根据上一节的结论,s1和s2的对界都取最大的元素类型,也就是double类型的对界8。然后开始摆放每个元素。
\r\n     对于s1,首先把a放到8的对界,假定是0,此时下一个空闲的地址是1,但是下一个元素d是double类型,要放到8的对界上,离1最接近的地址是8 了,所以d被放在了8,此时下一个空闲地址变成了16,下一个元素c的对界是4,16可以满足,所以c放在了16,此时下一个空闲地址变成了20,下一个 元素d需要对界1,也正好落在对界上,所以d放在了20,结构体在地址21处结束。由于s1的大小需要是8的倍数,所以21-23的空间被保留,s1的大 小变成了24。
\r\n
\r\n
\r\n     对于s2,首先把a放到8的对界,假定是0,此时下一个空闲地址是1,下一个元素的对界也是1,所以b摆放在1,下一个空闲地址变成了2;下一个元素c的 对界是4,所以取离2最近的地址4摆放c,下一个空闲地址变成了8,下一个元素d的对界是8,所以d摆放在8,所有元素摆放完毕,结构体在15处结束,占 用总空间为16,正好是8的倍数。
\r\n
\r\n    总结:这里计算sizeof既要考虑数据对齐(整体上最大元素的size对齐,满足之后还要满足struct中其他元素的对齐),又要考虑最节约存储空间的原则。

\r\n

\r\n    (3)、嵌套struct类定义中的sizeof
\r\n
\r\n 这里有个陷阱,对于结构体中的结构体成员,不要认为它的对齐方式就是他的大小,看下面的例子:

\r\n
\r\n  1 struct s1
\r\n  2  {
\r\n  3   char a[8];
\r\n  4  };
\r\n  5 
\r\n  6  struct s2
\r\n  7  {
\r\n  8   double d;
\r\n  9  };
\r\n 10 
\r\n 11  struct s3
\r\n 12  {
\r\n 13   s1 s;
\r\n 14   char a;
\r\n 15  };
\r\n 16 
\r\n 17  struct s4  //s1为1对齐,大小为8
\r\n 18  {
\r\n 19 
\r\n 20     s1 s;
\r\n 21     double d;
\r\n 22  };
\r\n 23 
\r\n 24  struct s5
\r\n 25  {
\r\n 26   s2 s;
\r\n 27   char a; 
\r\n 28  };
\r\n 29 
\r\n 30 
\r\n 31 
\r\n 32  cout << sizeof(s1) << endl; // 8
\r\n 33  cout << sizeof(s2) << endl; // 8
\r\n 34  cout << sizeof(s3) << endl; // 9
\r\n 35  cout << sizeof(s4) << endl; // 16
\r\n 36  cout << sizeof(s5) <<endl; //16
\r\n

\r\n  再考虑:

\r\n
\r\n  1 struct s1
\r\n  2  {
\r\n  3   char a[9];
\r\n  4  };
\r\n  5 
\r\n  6  struct s2
\r\n  7  {
\r\n  8   double d;
\r\n  9  };
\r\n 10 
\r\n 11  struct s3
\r\n 12  {
\r\n 13   s1 s;
\r\n 14   char a;
\r\n 15  };
\r\n 16 
\r\n 17  struct s4 //s1为1对齐,大小为9
\r\n 18  {
\r\n 19 
\r\n 20     s1 s;
\r\n 21     double d;
\r\n 22  };
\r\n 23 
\r\n 24  struct s5
\r\n 25  {
\r\n 26   s2 s;
\r\n 27   char a; 
\r\n 28  };
\r\n 29 
\r\n 30 
\r\n 31 
\r\n 32  cout << sizeof(s1) << endl; // 9
\r\n 33  cout << sizeof(s2) << endl; // 8
\r\n 34  cout << sizeof(s3) << endl; // 10
\r\n 35  cout << sizeof(s4) << endl; // 24
\r\n 36  cout << sizeof(s5) <<endl; //16
\r\n

\r\n  

\r\n

\r\n     s1和s2大小虽然都是8,但是s1的对齐方式是1,s2是8(double),所以在s3和s4中才有这样的差异。

\r\n

\r\n     所以,在自己定义结构体的时候,如果空间紧张的话,最好考虑对齐因素来排列结构体里的元素。

\r\n

\r\n (4)、位域结构体中的对齐问题。
\r\n                
\r\n     在结构体和类中,可以使用位域来规定某个成员所能占用的空间,所以使用位域能在一定程度上节省结构体占用的空间。不过考虑下面的代码:

\r\n
\r\n  1 struct s1
\r\n  2  {
\r\n  3   int i: 8;
\r\n  4   int j: 4;
\r\n  5   double b;
\r\n  6   int a:3;
\r\n  7  };
\r\n  8 
\r\n  9  struct s2
\r\n 10  {
\r\n 11   int i;
\r\n 12   int j;
\r\n 13   double b;
\r\n 14   int a;
\r\n 15  };
\r\n 16 
\r\n 17  struct s3
\r\n 18  {
\r\n 19   int i;
\r\n 20   int j;
\r\n 21   int a;
\r\n 22   double b;
\r\n 23  };
\r\n 24 
\r\n 25  struct s4
\r\n 26  {
\r\n 27   int i: 8;
\r\n 28   int j: 4;
\r\n 29   int a:3;
\r\n 30   double b;
\r\n 31  };
\r\n 32 
\r\n 33  struct s4
\r\n 34  {
\r\n 35   double b;
\r\n 36   int i: 8;
\r\n 37   int j: 4;
\r\n 38   int a:3;
\r\n 39  };
\r\n 40 
\r\n 41  cout<<sizeof(s1)<<endl;  // 24
\r\n 42  cout<<sizeof(s2)<<endl;  // 24
\r\n 43  cout<<sizeof(s3)<<endl;  // 24
\r\n 44  cout<<sizeof(s4)<<endl;  // 16
\r\n 45  cout<<sizeof(s5)<<endl;  // 16
\r\n 46 
\r\n 47     
\r\n 48
\r\n

\r\n 可以看到,有double存在会干涉到位域(sizeof的算法参考上一节),所以使用位域的的时候,最好把float类型和double类型放在程序的开始或者最后。不要让double干扰你的位域
\r\n
\r\n 五、类class 中的sizeof特别探讨
\r\n    
\r\n    写在前面,本节假设你看过《Inside the C++ Object Model》,如果没有,最好了解类与对象在内存中map问题
\r\n
\r\n    这里引用《Inside the C++ Object Model》中的对象模型的内存镜像图:
\r\n
\r\n (一)不考虑继承关系(单继承、多继承、虚继承等)
\r\n   (1)不带virtual函数时
\r\n             
\r\n         空类:

\r\n
\r\n 1 class A
\r\n 2 {
\r\n 3 
\r\n 4 };
\r\n 5 
\r\n 6 cout << sizeof(A) << endl; // 1
\r\n

\r\n      空类总是返回1

\r\n
\r\n  1 class B {
\r\n  2     private :
\r\n  3          int value;
\r\n  4         double a;
\r\n  5     public:
\r\n  6 
\r\n  7 };
\r\n  8 
\r\n  9 cout << sizeof(B) << endl; //16
\r\n 10
\r\n

\r\n    和struct一样,也要考虑对齐问题,以及成员的顺序
\r\n    因为成员函数不会分配空间,所以sizeof时只计算数据成员的大小
\r\n         
\r\n   (2)带virtual函数时
\r\n             单继承情况下,只要class中存在virtual函数,编译器在编译时就会自动插入一个指向虚函数表的指针vptr(大小为4字节). 不同的编译器vptr插入的位置可能不同,VC编译器插入vptr的位置一般是数据成员开始。
\r\n
\r\n 下例在MinGW Develper Studio2.05(gcc)下编译,VC 6.0编译器下结果为24  24, 我不太理解为什么...

\r\n
\r\n  1 class A
\r\n  2 {
\r\n  3 public:
\r\n  4      virtual void foo() {}
\r\n  5 private:
\r\n  6      int m1;
\r\n  7      double m2;
\r\n  8 };
\r\n  9 
\r\n 10 class B
\r\n 11 {
\r\n 12 public:
\r\n 13      virtual void foo() {}
\r\n 14 private:
\r\n 15      double m2;
\r\n 16      int m1;
\r\n 17 };
\r\n 18 
\r\n 19 
\r\n 20 cout << sizeof(A) << endl; // 16
\r\n 21 cout << sizeof(B) << endl; // 24
\r\n

\r\n
\r\n
\r\n   (3)带static成员时

\r\n
\r\n 1 class A {
\r\n 2     private :
\r\n 3          int value;
\r\n 4          double a;
\r\n 5          static int CST;
\r\n 6     public:
\r\n 7 };
\r\n 8 
\r\n 9 cout << sizeof(A) << endl; //16
\r\n

\r\n       因为static成员是分配在全局区为类的所有对象共享(VC编译器可能为了方便将其放入文字常量表), sizeof时不应该计入sttic成员
\r\n
\r\n (二)继承关系下
\r\n    (1)单继承情况下
\r\n               总体上讲, 派生类中需要考虑基类子类型(subtype)的问题,派生对象要考虑基类子对象的问题。

\r\n
\r\n  1 class A
\r\n  2 {
\r\n  3 public:
\r\n  4 
\r\n  5 private:
\r\n  6      int m1;
\r\n  7      double m2;
\r\n  8 };
\r\n  9 
\r\n 10 class B : public A
\r\n 11 {
\r\n 12 public:
\r\n 13 
\r\n 14 private:
\r\n 15      int m3;
\r\n 16 };
\r\n 17 
\r\n 18 cout << sizeof(A) << endl; // 16
\r\n 19 cout << sizeof(B) << endl; // 24
\r\n 20
\r\n

\r\n 同样,要考虑陷阱:基类对齐字节不等于大小,如下例:

\r\n
\r\n  1 class A
\r\n  2 {
\r\n  3 public:
\r\n  4 
\r\n  5 private:
\r\n  6      char m1[8];
\r\n  7 
\r\n  8 };
\r\n  9 
\r\n 10 class B : public A
\r\n 11 {
\r\n 12 public:
\r\n 13 
\r\n 14 private:
\r\n 15      char m3;
\r\n 16 };
\r\n 17 
\r\n 18 cout << sizeof(A) << endl; // 8
\r\n 19 cout << sizeof(B) << endl; // 9
\r\n 20 
\r\n 21
\r\n

\r\n  

\r\n
\r\n  1 class A
\r\n  2 {
\r\n  3 public:
\r\n  4 
\r\n  5 private:
\r\n  6      char m1[9];
\r\n  7 
\r\n  8 };
\r\n  9 
\r\n 10 class B : public A
\r\n 11 {
\r\n 12 public:
\r\n 13 
\r\n 14 private:
\r\n 15      int m3;
\r\n 16 };
\r\n 17 
\r\n 18 cout << sizeof(A) << endl; // 9
\r\n 19 cout << sizeof(B) << endl; // 16
\r\n 20 
\r\n 21
\r\n

\r\n 同样道理,如果一直继承下去,考虑的问题同上。有虚函数不要忘记vptr指针
\r\n
\r\n    (2)多继承与虚继承情况下
\r\n
\r\n            (待有空了再研究)....
\r\n
\r\n (三)类的sizeof与对象的sizeof一样吗?
\r\n
\r\n
\r\n 另外,C99标准的sizeof已经可以工作在运行时了,打算最近找个支持C99的编译器研究一下。

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2808, 'app-in-the-mfc-doc-view-class-differences', 'MFC中app doc view类区别', '2012-11-14 04:34:03', '2019-03-25 21:29:22', '
\r\n

\r\n       App类就是这个SDI作为"程序"的入口有点像c的Main函数
\r\n document/view模式     是为了在逻辑上,让数据和显示分开。

\r\n

\r\n       一般在document里,定义document类的成员变量,来存数据,并用View来显示.

\r\n

\r\n       在document里,当成员变量的数据改变时,你可以用UpdateAllViews()来通知视图更新

\r\n

\r\n       在View里,用GetDocument来获取与之对应document的指针,进而可以访问document的成员变量,从而进行显示Document/View仅仅是MFC为你提供的一种很好的支持而已.

\r\n

\r\n       view类是在框架类之上,所以如果你需要实现画面显示之类的,就只能在VIEW类中响应.
\r\n 基本上文档类是用于存储数据管理的类,而视图类是用来显示数据结果的类,他们一般情况下是关联的,因为他们息息相关,一个存储、一个显示

\r\n

\r\n       另外App类和Doc类都是从CCmdTarget类派生而来,所以只能接收命令消息和控件通知消息,View类与Frame框架类都是从CWnd类派生所以能够接收命令消息和控件通知消息还有windows消息三种消息.对于三种消息,期响应的顺序是这样的:

\r\n

\r\n        首先由框架类接收到该消息,框架类将该消息递交给其子窗口View,如果View没有对该消息进行响应,则由View递交给Doc,如果Doc也没有对该 消息进行响应,那么它回再次将该消息回交给View,View再回交给Frame框架,框架检查自己是否对该消息有相应的处理函数,如果没有则递交给 App,如果App也没有则由Windows系统自己处理。

\r\n

\r\n       所以另外一个顺序问题.在doc类定义的还是会回交给view类。

\r\n
\r\n
\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2809, 'ckeditor-uses-in-asp-net', 'CKEditor 在ASP.NET中的使用', '2012-11-14 04:27:31', '2019-03-25 21:29:22', '

\r\n       CKEditor是来源自FCKEditor,是一个WYSIWYG的可视化编辑工具。FCKEditro的名字一直延续至2.X时代,后来的版本就变成了CKEditor,

\r\n

\r\n 官方网站地址:http://ckeditor.com/

\r\n

\r\n       对于asp.net,CKEditor3.*.x已经不包含一个dll的动态链接库。不过通过使用CKEditor可以是asp.net中的multiline状态的textbox 控件转为一个富文本的编辑器。当然了你也可以将P或者div转变为一个编辑器(对于最新3.6.4版本,有更简便的用法,不必做此转换,在此不做细说,请参考我的后续文章),步骤如下:

\r\n

\r\n 1.打开 Visual studio 2008(2005一样),新建一个站点

\r\n

\r\n 2.下载CKEditor   http://ckeditor.com/download

\r\n

\r\n 3.解压缩文件,复制ckeditor文件进入你的站点

\r\n

\r\n \"

\r\n

\r\n 4.拖动一个textbox进入aspx页面,同时设置textmode为multiline,该id为TextBox1

\r\n

\r\n 5.把ckeditor.js包含入头文件

\r\n

\r\n    <script type="text/javascript" language="javascript" src="ckeditor/ckeditor.js"></script>

\r\n

\r\n 6.调用ckeditor的javascript api 把该textbox转换为编辑器

\r\n

\r\n CKEDITOR.replace('TextBox1')

\r\n

\r\n 调用方法(两种方法)

\r\n

\r\n 第一种为是使用window.onload

\r\n

\r\n <script type="text/javascript">

\r\n

\r\n      window.onload=function()

\r\n

\r\n      {

\r\n

\r\n      CKEDITOR.replace('TextBox1');

\r\n

\r\n      }

\r\n

\r\n </script>

\r\n

\r\n 另外一种在你的multiline textbox后面使用(这里我就使用这一种)

\r\n

\r\n <div>
\r\n       <asp:TextBox ID="TextBox1" TextMode="MultiLine" runat="server"></asp:TextBox>

\r\n

\r\n     <script type="text/javascript">       

\r\n

\r\n         CKEDITOR.replace('TextBox1');

\r\n

\r\n </script>
\r\n </div>

\r\n  

\r\n

\r\n 7.运行以后可以发现代码被替换成了编辑器

\r\n

\r\n \"

\r\n

\r\n    完成后的代码如下:

\r\n

\r\n <head runat="server">

\r\n

\r\n     <title></title>

\r\n

\r\n     <script type="text/javascript" src="ckeditor/ckeditor.js"></script>    

\r\n

\r\n </head>

\r\n

\r\n <body>

\r\n

\r\n     <form id="form1" runat="server">

\r\n

\r\n     <div>

\r\n

\r\n         <asp:TextBox ID="TextBox1" TextMode="MultiLine" runat="server"></asp:TextBox>

\r\n

\r\n     <script type="text/javascript">       

\r\n

\r\n         CKEDITOR.replace('TextBox1');

\r\n

\r\n     </script>

\r\n

\r\n     </div>

\r\n

\r\n     <asp:Button ID="btnSave" runat="server" Text="Save" onclick="btnSave_Click" />

\r\n

\r\n     </form>

\r\n

\r\n </body>

\r\n

\r\n </html>

\r\n

\r\n CKEDITOR的配置

\r\n

\r\n 默认情况下如上图,会发现有很多的功能和图标,实际中我们是需要自己进行定义以便符合自己的需求

\r\n

\r\n 1.使用CKEDITOR的替换功能进行定制

\r\n

\r\n 默认编辑器包含两种toolbar设置,full和Basic,下面演示如何设定为Basic

\r\n

\r\n <script type="text/javascript">

\r\n

\r\n         CKEDITOR.replace('TextBox1', {toolbar:'Basic'});      

\r\n

\r\n </script>
\r\n  

\r\n

\r\n 或者自己定义设定如下

\r\n

\r\n <script type="text/javascript">

\r\n

\r\n         var config = {

\r\n

\r\n             toolbar:

\r\n

\r\n                       [

\r\n

\r\n                          ['Bold', 'Italic', '-', 'NumberedList', 'BulletedList', '-', 'Link', 'Unlink'],

\r\n

\r\n                          ['UIColor'], '/',

\r\n

\r\n                          ['Styles', 'Format', 'Font', 'FontSize']

\r\n

\r\n                       ]

\r\n

\r\n         };

\r\n

\r\n         CKEDITOR.replace('TextBox1', config);      

\r\n

\r\n     </script>

\r\n

\r\n 2.通过config.js进行定制

\r\n

\r\n 在ckeditor文件夹中找到config.js,打开可以看到默认的一些设置

\r\n

\r\n CKEDITOR.editorConfig = function( config )
\r\n {
\r\n // Define changes to default configuration here. For example:
\r\n // config.language = 'fr';
\r\n // config.uiColor = '#AADC6E';
\r\n };

\r\n

\r\n 添加自己的toolbar,如下

\r\n

\r\n CKEDITOR.editorConfig = function( config )

\r\n

\r\n {

\r\n

\r\n        // Define changes to default configuration here. For example:

\r\n

\r\n        // config.language = 'fr';

\r\n

\r\n     // config.uiColor = '#AADC6E';

\r\n

\r\n  

\r\n

\r\n  

\r\n

\r\n     config.toolbar_CodeDigestTool =

\r\n

\r\n     [  

\r\n

\r\n     ['Bold', 'Italic', 'Underline', 'Strike', '-', 'Subscript', 'Superscript'],

\r\n

\r\n     ['NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', 'Blockquote'],

\r\n

\r\n     ['JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock'],

\r\n

\r\n     ['Link', 'Unlink', 'Anchor'],

\r\n

\r\n     ['Image', 'Flash', 'Table', 'HorizontalRule', 'Smiley', 'SpecialChar', 'PageBreak'],

\r\n

\r\n     '/',

\r\n

\r\n     ['Styles', 'Format', 'Font', 'FontSize'],

\r\n

\r\n     ['TextColor', 'BGColor'],

\r\n

\r\n     ['Maximize', 'ShowBlocks', '-', 'About']

\r\n

\r\n     ];

\r\n

\r\n  

\r\n

\r\n };

\r\n

\r\n 这样你就可以引用你自己定义的toolbar了

\r\n

\r\n <script type="text/javascript">

\r\n

\r\n         CKEDITOR.replace('TextBox1', {toolbar:'CodeDigestTool'});      

\r\n

\r\n </script>

\r\n

\r\n 配置的内容可以参看http://hi.baidu.com/x2p2/blog/item/316729dfe149c71863279898.html

\r\n

\r\n 但是编辑config.js意味着你在改变默认的ckeditor的文件,为了防止这样的问题。那么我们可以把刚才的配置文件放置外部的文件,通过使用 javascript去调用外部的配置文件.下面演示了把文件保存为CodeDigest_config.js然后使用的时候从custom目录进行调用

\r\n

\r\n CKEDITOR.replace( ' TextBox1',

\r\n

\r\n     {

\r\n

\r\n         customConfig : '/Custom/CodeDigest_config.js'

\r\n

\r\n     });

\r\n

\r\n 这样大体完成了。但是你运行然后提交会发生下面的错误

\r\n

\r\n A potentially dangerous Request.Form value was detected from the client (TextBox1="").

\r\n

\r\n 因为默认情况下ASP.NET是不允许HTML的输入提交给服务器端,所以你需要修改ValidateRequest="false"

\r\n

\r\n <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" ValidateRequest="false" %>

\r\n

\r\n 附录:参考配置

\r\n

\r\n CKEDITOR.editorConfig = function( config )
\r\n {
\r\n      config.language = 'zh-cn';//中文
\r\n     
config.uiColor = '#BFEE62';//编辑器颜色
\r\n      config.font_names = '宋体;楷体_GB2312;新宋体;黑体;隶书;幼圆;微软雅黑;Arial;Comic Sans MS;Courier New;Tahoma;Times New Roman;Verdana';
\r\n
\r\n     config.toolbar_Full =
\r\n     [
\r\n         ['Source','-','Preview','-','Templates'],
\r\n         ['Cut','Copy','Paste','PasteText','PasteFromWord','-','Print', 'SpellChecker', 'Scayt'],
\r\n         ['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'],
\r\n         ['Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField'],
\r\n         '/',
\r\n         ['Bold','Italic','Underline','Strike','-','Subscript','Superscript'],
\r\n         ['NumberedList','BulletedList','-','Outdent','Indent','Blockquote','CreateDiv'],
\r\n         ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'],
\r\n         ['Link','Unlink','Anchor'],
\r\n           ['Image','Flash','Table','HorizontalRule','Smiley','SpecialChar','PageBreak'],
\r\n         '/',
\r\n         ['Styles','Format','Font','FontSize'],
\r\n         ['TextColor','BGColor'],
\r\n         ['Maximize', 'ShowBlocks','-','About']
\r\n     ];
\r\n
\r\n     config.toolbar_Basic =
\r\n     [
\r\n         ['Bold', 'Italic', '-', 'NumberedList', 'BulletedList', '-', 'Link', 'Unlink','-','About']
\r\n     ];
\r\n
\r\n config.width =771;//宽度

\r\n

\r\n config.height = 250;//高度
\r\n
\r\n };

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2810, 'under-ubuntu-using-gvim', 'ubuntu下使用Gvim', '2012-11-14 04:16:32', '2019-03-25 21:29:22', '

\r\n 摘要

\r\n

\r\n   很多人也许和我一样,在ubuntu下都不知道如何配置vim,网络上也没有一个完整和比较好的配置方案(就是想在一个文件夹内自定义自己的配置,可以很方便打包移植到其他电脑上去。)花点时间,自己摸索一下,记录下这个过程。

\r\n

\r\n 安装GVim

\r\n

\r\n   终端下输入:

\r\n

\r\n sudo apt-get update
\r\n sudo apt-get install vim-gnome

\r\n

\r\n 另外,你也可以使用以下命令安装:

\r\n

\r\n sudo apt-get update
\r\n sudo apt-get install vim-gtk

\r\n

\r\n 这2个没有看出区别来。

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2811, 'wincvs-ccvsno-logon-appear-in-such-repository-solutions', 'WinCvs里登录出现C:/cvs: no such repository解决方案', '2012-11-14 04:15:44', '2019-03-25 21:29:22', '

\r\n cvsNt下载地址:
\r\n       http://www.march-hare.com/cvsnt/features/cvsnt/

\r\n

\r\n 问题描述:

\r\n

\r\n CVSNT中“no such repository”问题。   
\r\n 下面是控制台输出的内容:

\r\n

\r\n cvs -d :pserver:txshi@127.0.0.1:d:/cvs login
\r\n Logging in to :pserver:txshi@127.0.0.1:2401:d:/cvs
\r\n cvs [login aborted]: d:/cvs: no such repository

\r\n

\r\n ***** CVS exited normally with code 1 *****

\r\n

\r\n ------------------------------------------------------

\r\n

\r\n 解决方案:将d:/CVS改为:/cvs,即,将前面的盘符去掉
\r\n 下面是控制台输出的内容:

\r\n

\r\n ------------------------------------------------------

\r\n

\r\n cvs -d :pserver:txshi@127.0.0.1:2401:/cvs login
\r\n Logging in to :pserver:txshi@127.0.0.1:2401:/cvs

\r\n

\r\n ***** CVS exited normally with code 0 *****
\r\n ------------------------------------------------------

\r\n

\r\n 原因分析:CVSNT用了Linux风格的目录,直接已/目录开头,不需要输入盘符。
\r\n  

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2812, 'detailed-explanation-of-kmp-algorithm-of-string-pattern-matching', 'KMP算法字符串模式匹配详解', '2012-11-14 04:12:25', '2019-03-25 21:29:22', '
\r\n       KMP字符串模式匹配通俗点说就是一种在一个字符串中定位另一个串的高效算法。简单匹配算法的时间复杂度为O(m*n),而KMP匹配算法,可以证明它的时间复杂度为O(m+n)。
\r\n
\r\n 一.简单匹配算法
\r\n
\r\n       先来看一个简单匹配算法的函数:
\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\nint Index_BF ( char S [ ], char T [ ], int pos )\r\n{\r\n/* 若串 S 中从第pos(S 的下标0≤pos<StrLength(S))个字符\r\n起存在和串 T 相同的子串,则称匹配成功,返回第一个\r\n这样的子串在串 S 中的下标,否则返回 -1    */\r\nint i = pos, j = 0;\r\nwhile ( S[i+j] != ' '&& T[j] != ' ')\r\nif ( S[i+j] == T[j] )\r\nj ++; // 继续比较后一字符\r\nelse\r\n{\r\ni ++; j = 0; // 重新开始新的一轮匹配\r\n}\r\nif ( T[j] == ' ')\r\nreturn i; // 匹配成功   返回下标\r\nelse\r\nreturn -1; // 串S中  (第pos个字符起)不存在和串T相同的子串\r\n} // Index_BF
\r\n
\r\n
\r\n
\r\n        此算法的思想是直截了当的:将主串S中某个位置i起始的子串和模式串T相比较。即从j=0 起比较 S[i+j] 与 T[j],若相等,则在主串 S 中存在以 i 为起始位置匹配成功的可能性,继续往后比较( j逐步增1 ),直至与T串中最后一个字符相等为止,否则改从S串的下一个字符起重新开始进行下一轮的"匹配",即将串T向后滑动一位,即 i 增1,而 j 退回至0,重新开始新一轮的匹配。
\r\n
\r\n       例如:在串S=”abcabcabdabba”中查找T=” abcabd”(我们可以假设从下标0开始):先是比较S[0]和T[0]是否相等,然后比较S[1] 和T[1]是否相等…我们发现一直比较到S[5] 和T[5]才不等。如图:
\r\n
\r\n \"\"
\r\n       当这样一个失配发生时,T下标必须回溯到开始,S下标回溯的长度与T相同,然后S下标增1,然后再次比较。如图:
\r\n
\r\n 这次立刻发生了失配,T下标又回溯到开始,S下标增1,然后再次比较。如图:
\r\n
\r\n \"\"
\r\n       这次立刻发生了失配,T下标又回溯到开始,S下标增1,然后再次比较。如图:
\r\n
\r\n \"\"
\r\n       又一次发生了失配,所以T下标又回溯到开始,S下标增1,然后再次比较。这次T中的所有字符都和S中相应的字符匹配了。函数返回T在S中的起始下标3。如图:
\r\n \"\"
\r\n
\r\n
\r\n 二. KMP匹配算法
\r\n
\r\n       还是相同的例子,在S=”abcabcabdabba”中查找T=”abcabd”,如果使用KMP匹配算法,当第一次搜索到S[5] 和T[5]不等后,S下标不是回溯到1,T下标也不是回溯到开始,而是根据T中T[5]==’d’的模式函数值(next[5]=2,为什么?后面讲),直接比较S[5] 和T[2]是否相等,因为相等,S和T的下标同时增加;因为又相等,S和T的下标又同时增加,最终在S中找到了T。如图:
\r\n
\r\n \"\"
\r\n       KMP匹配算法和简单匹配算法效率比较,一个极端的例子是:
\r\n
\r\n       在S=“AAAAAA…AAB“(100个A)中查找T=”AAAAAAAAAB”, 简单匹配算法每次都是比较到T的结尾,发现字符不同,然后T的下标回溯到开始,S的下标也要回溯相同长度后增1,继续比较。如果使用KMP匹配算法,就不必回溯.
\r\n
\r\n       对于一般文稿中串的匹配,简单匹配算法的时间复杂度可降为O (m+n),因此在多数的实际应用场合下被应用。
\r\n
\r\n       KMP算法的核心思想是利用已经得到的部分匹配信息来进行后面的匹配过程。看前面的例子。为什么T[5]==’d’的模式函数值等于2(next[5]=2),其实这个2表示T[5]==’d’的前面有2个字符和开始的两个字符相同,且T[5]==’d’不等于开始的两个字符之后的第三个字符(T[2]=’c’).如图:
\r\n
\r\n \"\"
\r\n
\r\n       也就是说,如果开始的两个字符之后的第三个字符也为’d’,那么,尽管T[5]==’d’的前面有2个字符和开始的两个字符相同,T[5]==’d’的模式函数值也不为2,而是为0。
\r\n
\r\n       前面我说:在S=”abcabcabdabba”中查找T=”abcabd”,如果使用KMP匹配算法,当第一次搜索到S[5] 和T[5]不等后,S下标不是回溯到1,T下标也不是回溯到开始,而是根据T中T[5]==’d’的模式函数值,直接比较S[5] 和T[2]是否相等,为什么可以这样?
\r\n
\r\n       刚才我又说:“(next[5]=2),其实这个2表示T[5]==’d’的前面有2个字符和开始的两个字符相同”。请看图 :因为,S[4] ==T[4],S[3] ==T[3],根据next[5]=2,有T[3]==T[0],T[4] ==T[1],所以S[3]==T[0],S[4] ==T[1](两对相当于间接比较过了),因此,接下来比较S[5] 和T[2]是否相等。。。
\r\n
\r\n \"\"
\r\n
\r\n       有人可能会问:S[3]和T[0],S[4] 和T[1]是根据next[5]=2间接比较相等,那S[1]和T[0],S[2] 和T[0]之间又是怎么跳过,可以不比较呢?因为S[0]=T[0],S[1]=T[1],S[2]=T[2],而T[0] != T[1], T[1] != T[2],==> S[0] != S[1],S[1] != S[2],所以S[1] != T[0],S[2] != T[0]. 还是从理论上间接比较了。
\r\n
\r\n 有人疑问又来了,你分析的是不是特殊轻况啊。
\r\n
\r\n       假设S不变,在S中搜索T=“abaabd”呢?答:这种情况,当比较到S[2]和T[2]时,发现不等,就去看next[2]的值,next[2]=-1,意思是S[2]已经和T[0] 间接比较过了,不相等,接下来去比较S[3]和T[0]吧。
\r\n       假设S不变,在S中搜索T=“abbabd”呢?答:这种情况当比较到S[2]和T[2]时,发现不等,就去看next[2]的值,next[2]=0,意思是S[2]已经和T[2]比较过了,不相等,接下来去比较S[2]和T[0]吧。
\r\n
\r\n       假设S=”abaabcabdabba”在S中搜索T=“abaabd”呢?答:这种情况当比较到S[5]和T[5]时,发现不等,就去看next[5]的值,next[5]=2,意思是前面的比较过了,其中,S[5]的前面有两个字符和T的开始两个相等,接下来去比较S[5]和T[2]吧。
\r\n
\r\n       总之,有了串的next值,一切搞定。那么,怎么求串的模式函数值next[n]呢?(本文中next值、模式函数值、模式值是一个意思。)
\r\n
\r\n 三. 怎么求串的模式值next[n]
\r\n
\r\n 定义:
\r\n
\r\n (1)next[0]= -1 
\r\n       意义:任何串的第一个字符的模式值规定为-1。
\r\n
\r\n (2)next[j]= -1  
\r\n       意义:模式串T中下标为j的字符,如果与首字符
相同,且j的前面的j—k个字符与开头的j—k个字符不等(或者相等但T[k]==T[j])(1≤k<j)。
\r\n
\r\n 如:T=”abCabCad” 则 next[6]=-1,因T[3]=T[6]
\r\n
\r\n (3)next[j]=k   
\r\n       意义:模式串T中下标为j的字符,如果j的前面k个
字符与开头的k个字符相等,且T[j] != T[k] (1≤k<j)。
\r\n
\r\n 即T[0]T[1]T[2]。。。T[k-1]==T[j-k]T[j-k+1]T[j-k+2]…T[j-1] 且T[j] != T[k].(1≤k<j);
\r\n
\r\n (4) next[j]=0  
\r\n       意义:除(1)(2)(3)的其他情况。
\r\n
\r\n  
\r\n
\r\n 举例:
\r\n
\r\n 01)求T=“abcac”的模式函数的值。
\r\n
\r\n      next[0]= -1 根据(1)
\r\n
\r\n      next[1]=0   根据 (4)   因(3)有1<=k<j;不能说,j=1,T[j-1]==T[0]
\r\n
\r\n      next[2]=0   根据 (4)   因(3)有1<=k<j;(T[0]=a)!=(T[1]=b)
\r\n
\r\n      next[3]= -1 根据 (2)
\r\n
\r\n      next[4]=1   根据 (3) T[0]=T[3] 且 T[1]!=T[4]
\r\n
\r\n     即   
\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n 下标
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 1
\r\n
\r\n
\r\n 2
\r\n
\r\n
\r\n 3
\r\n
\r\n
\r\n 4
\r\n
\r\n
\r\n T
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n b
\r\n
\r\n
\r\n c
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n c
\r\n
\r\n
\r\n next
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 1
\r\n
\r\n
\r\n 若T=“abcab”将是这样:
\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n 下标
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 1
\r\n
\r\n
\r\n 2
\r\n
\r\n
\r\n 3
\r\n
\r\n
\r\n 4
\r\n
\r\n
\r\n T
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n b
\r\n
\r\n
\r\n c
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n b
\r\n
\r\n
\r\n next
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 为什么T[0]==T[3],还会有next[4]=0呢, 因为T[1]==T[4], 根据 (3)” 且T[j] != T[k]”被划入(4)。
\r\n
\r\n 02)来个复杂点的,求T=”ababcaabc” 的模式函数的值。
\r\n
\r\n next[0]= -1    根据(1)
\r\n
\r\n next[1]=0    根据(4)
\r\n
\r\n next[2]=-1   根据 (2)
\r\n
\r\n next[3]=0   根据 (3) 虽T[0]=T[2] 但T[1]=T[3] 被划入(4)
\r\n
\r\n next[4]=2   根据 (3) T[0]T[1]=T[2]T[3] 且T[2] !=T[4]
\r\n
\r\n next[5]=-1 根据 (2) 
\r\n
\r\n next[6]=1   根据 (3) T[0]=T[5] 且T[1]!=T[6]
\r\n
\r\n next[7]=0   根据 (3) 虽T[0]=T[6] 但T[1]=T[7] 被划入(4)
\r\n
\r\n next[8]=2   根据 (3) T[0]T[1]=T[6]T[7] 且T[2] !=T[8]
\r\n
\r\n  即
\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n 下标
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 1
\r\n
\r\n
\r\n 2
\r\n
\r\n
\r\n 3
\r\n
\r\n
\r\n 4
\r\n
\r\n
\r\n 5
\r\n
\r\n
\r\n 6
\r\n
\r\n
\r\n 7
\r\n
\r\n
\r\n 8
\r\n
\r\n
\r\n T
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n b
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n b
\r\n
\r\n
\r\n c
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n b
\r\n
\r\n
\r\n c
\r\n
\r\n
\r\n next
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 2
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 2
\r\n
\r\n
\r\n 只要理解了next[3]=0,而不是=1,next[6]=1,而不是= -1,next[8]=2,而不是= 0,其他的好象都容易理解。
\r\n
\r\n 03)   来个特殊的,求 T=”abCabCad” 的模式函数的值。
\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n 下标
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 1
\r\n
\r\n
\r\n 2
\r\n
\r\n
\r\n 3
\r\n
\r\n
\r\n 4
\r\n
\r\n
\r\n 5
\r\n
\r\n
\r\n 6
\r\n
\r\n
\r\n 7
\r\n
\r\n
\r\n T
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n b
\r\n
\r\n
\r\n C
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n b
\r\n
\r\n
\r\n C
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n d
\r\n
\r\n
\r\n next
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 4
\r\n
\r\n
\r\n next[0]= -1
\r\n next[1]= 0
\r\n next[2]= 0
\r\n next[3]= -1
\r\n next[4]= 0     
\r\n
\r\n next[5]= 0 根据 (3) 虽T[0]T[1]=T[3]T[4],但T[2]==T[5]
\r\n
\r\n next[6]= -1 根据 (2) 虽前面有abC=abC,但T[3]==T[6]
\r\n
\r\n next[7]=4   根据 (3) 前面有abCa=abCa,且 T[4]!=T[7]
\r\n
\r\n 若T[4]==T[7],即T=” adCadCad”,那么将是这样:next[7]=0, 而不是= 4,因为T[4]==T[7].
\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n 下标
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 1
\r\n
\r\n
\r\n 2
\r\n
\r\n
\r\n 3
\r\n
\r\n
\r\n 4
\r\n
\r\n
\r\n 5
\r\n
\r\n
\r\n 6
\r\n
\r\n
\r\n 7
\r\n
\r\n
\r\n T
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n d
\r\n
\r\n
\r\n C
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n d
\r\n
\r\n
\r\n C
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n d
\r\n
\r\n
\r\n next
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n  
\r\n
\r\n 如果你觉得有点懂了,那么
\r\n
\r\n 练习:求T=”AAAAAAAAAAB” 的模式函数值,并用后面的求模式函数值函数验证。
\r\n
\r\n 意义:
\r\n
\r\n       next 函数值究竟是什么含义,前面说过一些,这里总结。
\r\n
\r\n 设在字符串S中查找模式串T,若S[m]!=T[n],那么,取T[n]的模式函数值next[n]
\r\n
\r\n 1. next[n]= -1 表示S[m]和T[0]间接比较过了,不相等,下一次比较 S[m+1] 和T[0]
\r\n
\r\n 2.next[n]=0 表示比较过程中产生了不相等,下一次比较 S[m] 和T[0]。
\r\n
\r\n 3.next[n]= k >0 但k<n, 表示,S[m]的前k个字符与T中的开始k个字符已经间接比较相等了,下一次比较S[m]和T[k]相等吗?
\r\n
\r\n 4.其他值,不可能。
\r\n
\r\n 四. 求串T的模式值next[n]的函数
\r\n
\r\n       说了这么多,是不是觉得求串T的模式值next[n]很复杂呢?要叫我写个函数出来,目前来说,我宁愿去登天。好在有现成的函数,当初发明KMP算法,写出这个函数的先辈,令我佩服得六体投地。我等后生小子,理解起来,都要反复琢磨。下面是这个函数:
\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\nvoid get_nextval(const char *T, int next[])\r\n{\r\n       // 求模式串T的next函数值并存入数组 next。\r\n       int j = 0, k = -1;\r\n       next[0] = -1;\r\n       while ( T[j/*+1*/] != '/0' )\r\n       {\r\n              if (k == -1 || T[j] == T[k])\r\n              {\r\n                     ++j; ++k;\r\n                     if (T[j]!=T[k])\r\n                            next[j] = k;\r\n                     else\r\n                            next[j] = next[k];\r\n              }// if\r\n              else\r\n                     k = next[k];\r\n       }// while\r\n    ////这里是我加的显示部分\r\n   // for(int i=0;i<j;i++)\r\n       //{\r\n       //     cout<<next[i];\r\n       //}\r\n       //cout<<endl;\r\n}// get_nextval 
\r\n
\r\n
\r\n
\r\n 另一种写法,也差不多。
\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\nvoid getNext(const char* pattern,int next[])\r\n{\r\n       next[0]=   -1;\r\n       int k=-1,j=0;\r\n       while(pattern[j] != '/0')\r\n       {\r\n              if(k!= -1 && pattern[k]!= pattern[j] )\r\n                     k=next[k];\r\n              ++j;++k;\r\n              if(pattern[k]== pattern[j])\r\n                     next[j]=next[k];\r\n              else\r\n                     next[j]=k;\r\n       }\r\n       ////这里是我加的显示部分\r\n   // for(int i=0;i<j;i++)\r\n       //{\r\n       //     cout<<next[i];\r\n       //}\r\n       //cout<<endl;\r\n} 
\r\n
\r\n
\r\n
\r\n 下面是KMP模式匹配程序,各位可以用他验证。记得加入上面的函数
\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n#include <iostream.h>\r\n#include <string.h>\r\nint KMP(const char *Text,const char* Pattern) //const 表示函数内部不会改变这个参数的值。\r\n{\r\n       if( !Text||!Pattern|| Pattern[0]=='/0' || Text[0]=='/0' )//\r\n              return -1;//空指针或空串,返回-1。\r\n       int len=0;\r\n       const char * c=Pattern;\r\n       while(*c++!='/0')//移动指针比移动下标快。\r\n       {\r\n              ++len;//字符串长度。\r\n       }\r\n       int *next=new int[len+1];\r\n       get_nextval(Pattern,next);//求Pattern的next函数值\r\n\r\n       int index=0,i=0,j=0;\r\n       while(Text[i]!='/0' && Pattern[j]!='/0' )\r\n       {\r\n              if(Text[i]== Pattern[j])\r\n              {\r\n                     ++i;// 继续比较后继字符\r\n                     ++j;\r\n              }\r\n              else\r\n              {\r\n                     index += j-next[j];\r\n                     if(next[j]!=-1)\r\n                            j=next[j];// 模式串向右移动\r\n                     else\r\n                     {\r\n                            j=0;\r\n                            ++i;\r\n                     }\r\n              }\r\n       }//while\r\n\r\n       delete []next;\r\n       if(Pattern[j]=='/0')\r\n              return index;// 匹配成功\r\n       else\r\n              return -1;\r\n}\r\nint main()//abCabCad\r\n{\r\n       char* text="bababCabCadcaabcaababcbaaaabaaacababcaabc";\r\n    char*pattern="adCadCad";\r\n       //getNext(pattern,n);\r\n    //get_nextval(pattern,n);\r\n      cout<<KMP(text,pattern)<<endl;\r\n       return 0;\r\n}\r\n
\r\n
\r\n
\r\n
\r\n 五.其他表示模式值的方法
\r\n
\r\n       上面那种串的模式值表示方法是最优秀的表示方法,从串的模式值我们可以得到很多信息,以下称为第一种表示方法。第二种表示方法,虽然也定义next[0]= -1,但后面绝不会出现-1,除了next[0],其他模式值next[j]=k(0≤k<j)的意义可以简单看成是:下标为j的字符的前面最多k个字符与开始的k个字符相同,这里并不要求T[j] != T[k]。其实next[0]也可以定义为0(后面给出的求串的模式值的函数和串的模式匹配的函数,是next[0]=0的),这样,next[j]=k(0≤k<j)的意义都可以简单看成是:下标为j的字符的前面最多k个字符与开始的k个字符相同。第三种表示方法是第一种表示方法的变形,即按第一种方法得到的模式值,每个值分别加1,就得到第三种表示方法。第三种表示方法,我是从论坛上看到的,没看到详细解释,我估计是为那些这样的编程语言准备的:数组的下标从1开始而不是0。
\r\n
\r\n       下面给出几种方法的例子:
\r\n
\r\n       表一。
\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n 下标
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 1
\r\n
\r\n
\r\n 2
\r\n
\r\n
\r\n 3
\r\n
\r\n
\r\n 4
\r\n
\r\n
\r\n 5
\r\n
\r\n
\r\n 6
\r\n
\r\n
\r\n 7
\r\n
\r\n
\r\n 8
\r\n
\r\n
\r\n T
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n b
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n b
\r\n
\r\n
\r\n c
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n b
\r\n
\r\n
\r\n c
\r\n
\r\n
\r\n (1) next
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 2
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 2
\r\n
\r\n
\r\n (2) next
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 1
\r\n
\r\n
\r\n 2
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 1
\r\n
\r\n
\r\n 1
\r\n
\r\n
\r\n 2
\r\n
\r\n
\r\n (3) next
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 1
\r\n
\r\n
\r\n 3
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 2
\r\n
\r\n
\r\n 1
\r\n
\r\n
\r\n 3
\r\n
\r\n
\r\n       第三种表示方法,在我看来,意义不是那么明了,不再讨论。
\r\n
\r\n       表二。
\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n 下标
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 1
\r\n
\r\n
\r\n 2
\r\n
\r\n
\r\n 3
\r\n
\r\n
\r\n 4
\r\n
\r\n
\r\n T
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n b
\r\n
\r\n
\r\n c
\r\n
\r\n
\r\n A
\r\n
\r\n
\r\n c
\r\n
\r\n
\r\n (1)next
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 1
\r\n
\r\n
\r\n (2)next
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 1
\r\n
\r\n
\r\n       表三。
\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n 下标
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 1
\r\n
\r\n
\r\n 2
\r\n
\r\n
\r\n 3
\r\n
\r\n
\r\n 4
\r\n
\r\n
\r\n 5
\r\n
\r\n
\r\n 6
\r\n
\r\n
\r\n 7
\r\n
\r\n
\r\n T
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n d
\r\n
\r\n
\r\n C
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n d
\r\n
\r\n
\r\n C
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n d
\r\n
\r\n
\r\n (1)next
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n (2)next
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 1
\r\n
\r\n
\r\n 2
\r\n
\r\n
\r\n 3
\r\n
\r\n
\r\n 4
\r\n
\r\n
\r\n  
\r\n
\r\n       对比串的模式值第一种表示方法和第二种表示方法,看表一:
\r\n
\r\n 第一种表示方法next[2]= -1,表示T[2]=T[0],且T[2-1] !=T[0]
\r\n
\r\n 第二种表示方法next[2]= 0,表示T[2-1] !=T[0],但并不管T[0] 和T[2]相不相等。
\r\n
\r\n 第一种表示方法next[3]= 0,表示虽然T[2]=T[0],但T[1] ==T[3]
\r\n
\r\n 第二种表示方法next[3]= 1,表示T[2] =T[0],他并不管T[1] 和T[3]相不相等。
\r\n
\r\n 第一种表示方法next[5]= -1,表示T[5]=T[0],且T[4] !=T[0],T[3]T[4] !=T[0]T[1],T[2]T[3]T[4] !=T[0]T[1]T[2]
\r\n
\r\n 第二种表示方法next[5]= 0,表示T[4] !=T[0],T[3]T[4] !=T[0]T[1] ,T[2]T[3]T[4] !=T[0]T[1]T[2],但并不管T[0] 和T[5]相不相等。换句话说:就算T[5]==’x’,或 T[5]==’y’,T[5]==’9’,也有next[5]= 0 。
\r\n
\r\n       从这里我们可以看到:串的模式值第一种表示方法能表示更多的信息,第二种表示方法更单纯,不容易搞错。当然,用第一种表示方法写出的模式匹配函数效率更高。比如说,在串S=“adCadCBdadCadCad 9876543”中匹配串T=“adCadCad”, 用第一种表示方法写出的模式匹配函数,当比较到S[6] != T[6] 时,取next[6]= -1(表三),它可以表示这样许多信息: S[3]S[4]S[5]==T[3]T[4]T[5]==T[0]T[1]T[2],而S[6] != T[6],T[6]==T[3]==T[0],所以S[6] != T[0],接下来比较S[7]和T[0]吧。如果用第二种表示方法写出的模式匹配函数,当比较到S[6] != T[6] 时,取next[6]= 3(表三),它只能表示:S[3]S[4]S[5]== T[3]T[4]T[5]==T[0]T[1]T[2],但不能确定T[6]与T[3]相不相等,所以,接下来比较S[6]和T[3];又不相等,取next[3]= 0,它表示S[3]S[4]S[5]== T[0]T[1]T[2],但不会确定T[3]与T[0]相不相等,即S[6]和T[0] 相不相等,所以接下来比较S[6]和T[0],确定它们不相等,然后才会比较S[7]和T[0]。是不是比用第一种表示方法写出的模式匹配函数多绕了几个弯。
\r\n
\r\n       为什么,在讲明第一种表示方法后,还要讲没有第一种表示方法好的第二种表示方法?原因是:最开始,我看严蔚敏的一个讲座,她给出的模式值表示方法是我这里的第二种表示方法,如图:
\r\n
\r\n 她说:“next 函数值的含义是:当出现S[i] !=T[j]时,下一次的比较应该在S[i]和T[next[j]] 之间进行。”虽简洁,但不明了,反复几遍也没明白为什么。而她给出的算法求出的模式值是我这里说的第一种表示方法next值,就是前面的get_nextval()函数。匹配算法也是有瑕疵的。
\r\n
\r\n       现在看来,她没有错,不过有张冠李戴之嫌。我不知道,是否有人第一次学到这里,不参考其他资料和明白人讲解的情况下,就能搞懂这个算法(我的意思是不仅是算法的大致思想,而是为什么定义和例子中next[j]=k(0≤k<j),而算法中next[j]=k(-1≤k<j))。 凭良心说:光看这个讲座,我就对这个教受十分敬佩,不仅讲课讲得好,声音悦耳,而且这门课讲得层次分明,恰到好处。在KMP这个问题上出了点小差错,可能是编书的时候,在这本书上抄下了例子,在那本书上抄下了算法,结果不怎么对得上号。因为我没找到原书,而据有的网友说,书上已不是这样,也许吧。说起来, 教授们研究的问题比这个高深不知多少倍,哪有时间推演这个小算法呢。总之,瑕不掩玉。
\r\n
\r\n 书归正传,下面给出我写的求第二种表示方法表示的模式值的函数,为了从S的任何位置开始匹配T,“当出现S[i] !=T[j]时,下一次的比较应该在S[i]和T[next[j]] 之间进行。”    定义next[0]=0 。
\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n void myget_nextval(const char *T, int next[])\r\n{\r\n     // 求模式串T的next函数值(第二种表示方法)并存入数组 next。\r\n     int j = 1, k = 0;\r\n     next[0] = 0;\r\n       while ( T[j] != '/0' )\r\n     {\r\n                   if(T[j] == T[k])\r\n                   {\r\n                         next[j] = k;\r\n                         ++j; ++k;\r\n                   }\r\n                   else if(T[j] != T[0])\r\n                   {\r\n                  next[j] = k;\r\n                  ++j;\r\n                           k=0;\r\n                   }\r\n                   else\r\n                   {\r\n                          next[j] = k;\r\n                  ++j;\r\n                             k=1;\r\n                   }\r\n     }//while\r\n    for(int i=0;i<j;i++)\r\n     {\r\n            cout<<next[i];\r\n     }\r\n     cout<<endl;\r\n}// myget_nextval\r\n
\r\n
\r\n
\r\n
\r\n       下面是模式值使用第二种表示方法的匹配函数(next[0]=0)
\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\nint my_KMP(char *S, char *T, int pos)\r\n{\r\nint i = pos, j = 0;//pos(S 的下标0≤pos<StrLength(S))\r\nwhile ( S[i] != '/0' && T[j] != '/0' )\r\n{\r\n    if (S[i] == T[j] )\r\n     {\r\n         ++i;\r\n             ++j; // 继续比较后继字符\r\n     }\r\n   else             // a b a b c a a b c\r\n                    // 0 0 0 1 2 0 1 1 2\r\n   {              //-1 0 -1 0 2 -1 1 0 2\r\n      i++;\r\n     j = next[j];     /*当出现S[i] !=T[j]时,\r\n              下一次的比较应该在S[i]和T[next[j]] 之间进行。要求next[0]=0。\r\n在这两个简单示范函数间使用全局数组next[]传值。*/\r\n   }\r\n}//while\r\nif ( T[j] == '/0' )\r\n    return (i-j); // 匹配成功\r\nelse\r\n     return -1;\r\n} // my_KMP\r\n
\r\n
\r\n
\r\n
\r\n 六.后话--KMP的历史
\r\n
\r\n       Cook于1970年证明的一个理论得到,任何一个可以使用被称为下推自动机的计算机抽象模型来解决的问题,也可以使用一个实际的计算机(更精确的说,使用一个随机存取机)在与问题规模对应的时间内解决。特别地,这个理论暗示存在着一个算法可以在大约m+n的时间内解决模式匹配问题,这里m和n分别是存储文本和模式串数组的最大索引。Knuth 和Pratt努力地重建了 Cook的证明,由此创建了这个模式匹配算法。大概是同一时间,Morris在考虑设计一个文本编辑器的实际问题的过程中创建了差不多是同样的算法。这里可以看到并不是所有的算法都是“灵光一现”中被发现的,而理论化的计算机科学确实在一些时候会应用到实际的应用中。
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2813, 'asp-net-jquery-verifies-that-the-user-name-exists', 'asp .net Jquery验证用户名是否存在', '2012-11-14 04:11:07', '2019-03-25 21:29:22', 'jQuery.ajax概述\r\n===============\r\n\r\nHTTP请求加载远程数据。\r\n\r\n通过jQuery底层AJAX实现。简单易用的高层实现见$.get, (.post等。).ajax()返回其创建的XMLHttpRequest对象。大多数情况下你无需直接操作该对象,但特殊情况下可用于手动终止请求。\r\n\r\n$.ajax()只有一个参数:参数key/value对象,包含各配置及回调函数信息。详细参数选项见下。\r\n 注意:如果你指定了dataType选项,请确保服务器返回正确的MIME信息,(如<u>**xml**</u>返回“text/xml”)。错误的MIME类型可能导致不可预知的错误。\r\n\r\n注意:如果dataType设置为“script”,那么在远程请求时(不在同一个域下),所有POST请求都将转为GET请求。(因为将使用DOM的script标签来加载)\r\n\r\njQuery 1.2中,您可以跨域加载JSON数据,使用时需将数据类型设置为<font color="#765f47">JSONP</font>。使用<font color="#765f47">JSONP</font>形式调用函数时,如“myurl?callback=?” jQuery将自动替换?为正确的函数名,以执行回调函数。数据类型设置为“jsonp”时,jQuery将自动调用回调函数。\r\n\r\n实例\r\n===\r\n\r\n1、请求页面AJax.aspx\r\n------------------\r\n\r\nhtml代码:\r\n```\r\n<div>\r\n <div id="showResult" style="float:left"></div>\r\n</div>\r\n```\r\n\r\n2.JS代码\r\n-------\r\n\r\n```\r\n function JudgeUserName()\r\n {\r\n $.ajax({\r\n type:"GET",\r\n url:"AjaxUserInfoModify.aspx",\r\n dataType:"html",\r\n data:"userName="+$("#txtName").val(),\r\n beforeSend:function(XMLHttpRequest)\r\n\r\n```', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2814, 'sql-server-2008-database-xxx-cannot-be-deleted-because', 'Sql Server 2008无法删除数据库XXX,因为...', '2012-11-13 13:47:24', '2019-03-25 21:29:22', '
\r\n

\r\n 解决方案:新建查询,输入以下语句,点击执行
\r\n  

\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\nuse master\r\ngo\r\ndeclare @dbname sysname\r\nset @dbname='testdata'                /*这个是要删除的数据库库名*/\r\ndeclare @s nvarchar(1000)\r\ndeclare tb cursor local for\r\nselect s='kill '+cast(spid as varchar)\r\nfrom master..sysprocesses\r\nwhere dbid=db_id(@dbname)\r\nopen tb\r\nfetch next from tb into @s\r\nwhile @@fetch_status=0\r\nbegin\r\nexec(@s)\r\nfetch next from tb into @s\r\nend\r\nclose tb\r\ndeallocate tb\r\nexec('drop database ['+@dbname+']')  
\r\n
\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2815, 'business-primary-keys-in-the-database-and-logical-primary-keys-composite-primary-keys-details', '数据库中业务主键、逻辑主键和复合主键详解', '2012-11-13 13:41:42', '2019-03-25 21:29:22', '

\r\n    在数据库的创建中,主键起着唯一表示元素的作用,其地位不言而喻。对逻辑主键、业务主键和复合主键的选择,将直接决定项目的性能。下面是自己基于 SQL Server 做的一些总结,其他数据库(Oracle、MySQL、DB2、......)应该也类似。

\r\n
\r\n

\r\n 定义:

\r\n

\r\n 主键(PRIMARY KEY):表通常具有包含唯一标识表中每一行的值的一列或一组列。这样的一列或多列称为表的主键 (PK),用于强制表的实体完整性。

\r\n

\r\n 外键(FOREIGN KEY):外键 (FK) 是用于建立和加强两个表数据之间的链接的一列或多列。在外键引用中,当一个表的列被引用作为另一个表的主键值的列时,就在两表之间创建了链接。这个列就成为第二个表的外键。

\r\n

\r\n 聚集索引:聚集索引基于数据行的键值在表内排序和存储这些数据行。每个表只能有一个聚集索引,因为数据行本身只能按一个顺序存储。

\r\n

\r\n 非聚集索引:非聚集索引包含索引键值和指向表数据存储位置的行定位器。可以对表或索引视图创建多个非聚集索引。通常,设计非聚集索引是为改善经常使用的、没有建立聚集索引的查询的性能。

\r\n

\r\n 自动编号列和标识符列:对于每个表,均可创建一个包含系统生成的序号值的标识符列,该序号值以唯一方式标识表中的每一行。

\r\n

\r\n 业务主键(自然主键):在数据库表中把具有业务逻辑含义的字段作为主键,称为“自然主键(Natural Key)”。

\r\n

\r\n 逻辑主键(代理主键):在数据库表中采用一个与当前表中逻辑信息无关的字段作为其主键,称为“代理主键”。

\r\n

\r\n 复合主键(联合主键):通过两个或者多个字段的组合作为主键。

\r\n

\r\n 原理分析:

\r\n

\r\n    使用逻辑主键的主要原因是,业务主键一旦改变则系统中关联该主键的部分的修改将会是不可避免的,并且引用越多改动越大。而使用逻辑主键则只需要修改 相应的业务主键相关的业务逻辑即可,减少了因为业务主键相关改变对系统的影响范围。业务逻辑的改变是不可避免的,因为“永远不变的是变化”,没有任何一个 公司是一成不变的,没有任何一个业务是永远不变的。最典型的例子就是身份证升位和驾驶执照号换用身份证号的业务变更。而且现实中也确实出现了身份证号码重复的情况,这样如果用身份证号码作为主键也带来了难以处理的情况。当然应对改变,可以有很多解决方案,方案之一是做一新系统与时俱进,这对软件公司来说确实是件好事。

\r\n

\r\n    使用逻辑主键的另外一个原因是,业务主键过大,不利于传输、处理和存储。我认为一般如果业务主键超过8字节就应该考虑使用逻辑主键了,因为int是 4字节的,bigint是8字节的,而业务主键一般是字符串,同样是 8 字节的 bigint 和 8 字节的字符串在传输和处理上自然是 bigint 效率更高一些。想象一下 code == "12345678" 和 id == 12345678 的汇编码的不同就知道了。当然逻辑主键不一定是 int 或者 bigint ,而业务主键也不一定是字符串也可以是 int 或 datetime 等类型,同时传输的也不一定就是主键,这个就要具体分析了,但是原理类似,这里只是讨论通常情况。同时如果其他表需要引用该主键的话,也需要存储该主键, 那么这个存储空间的开销也是不一样的。而且这些表的这个引用字段通常就是外键,或者通常也会建索引方便查找,这样也会造成存储空间的开销的不同,这也是需 要具体分析的。

\r\n

\r\n    使用逻辑主键的再一个原因是,使用 int 或者 bigint 作为外键进行联接查询,性能会比以字符串作为外键进行联接查询快。原理和上面的类似,这里不再重复。

\r\n

\r\n    使用逻辑主键的再一个原因是,存在用户或维护人员误录入数据到业务主键中的问题。例如错把 RMB 录入为 RXB ,相关的引用都是引用了错误的数据,一旦需要修改则非常麻烦。如果使用逻辑主键则问题很好解决,如果使用业务主键则会影响到其他表的外键数据,当然也可以 通过级联更新方式解决,但是不是所有都能级联得了的。

\r\n

\r\n    使用业务主键的主要原因是,增加逻辑主键就是增加了一个业务无关的字段,而用户通常都是对于业务相关的字段进行查找(比如员工的工号,书本的 ISBN No. ),这样我们除了为逻辑主键加索引,还必须为这些业务字段加索引,这样数据库的性能就会下降,而且也增加了存储空间的开销。所以对于业务上确实不常改变的 基础数据而言,使用业务主键不失是一个比较好的选择。另一方面,对于基础数据而言,一般的增、删、改都比较少,所以这部分的开销也不会太多,而如果这时候 对于业务逻辑的改变有担忧的话,也是可以考虑使用逻辑主键的,这就需要具体问题具体分析了。

\r\n

\r\n    使用业务主键的另外一个原因是,对于用户操作而言,都是通过业务字段进行的,所以在这些情况下,如果使用逻辑主键的话,必须要多做一次映射转换的动 作。我认为这种担心是多余的,直接使用业务主键查询就能得到结果,根本不用管逻辑主键,除非业务主键本身就不唯一。另外,如果在设计的时候就考虑使用逻辑 主键的话,编码的时候也是会以主键为主进行处理的,在系统内部传输、处理和存储都是相同的主键,不存在转换问题。除非现有系统是使用业务主键,要把现有系 统改成使用逻辑主键,这种情况才会存在转换问题。暂时没有想到还有什么场景是存在这样的转换的。

\r\n

\r\n    使用业务主键的再一个原因是,对于银行系统而言安全性比性能更加重要,这时候就会考虑使用业务主键,既可以作为主键也可以作为冗余数据,避免因为使 用逻辑主键带来的关联丢失问题。如果由于某种原因导致主表和子表关联关系丢失的话,银行可是会面临无法挽回的损失的。为了杜绝这种情况的发生,业务主键需 要在重要的表中有冗余存在,这种情况最好的处理方式就是直接使用业务主键了。例如身份证号、存折号、卡号等。所以通常银行系统都要求使用业务主键,这个需 求并不是出于性能的考虑而是出于安全性的考虑。

\r\n

\r\n    使用复合主键的主要原因和使用业务主键是相关的,通常业务主键只使用一个字段不能解决问题,那就只能使用多个字段了。例如使用姓名字段不够用了,再 加个生日字段。这种使用复合主键方式效率非常低,主要原因和上面对于较大的业务主键的情况类似。另外如果其他表要与该表关联则需要引用复合主键的所有字 段,这就不单纯是性能问题了,还有存储空间的问题了,当然你也可以认为这是合理的数据冗余,方便查询,但是感觉有点得不偿失。

\r\n

\r\n    使用复合主键的另外一个原因是,对于关系表来说必须关联两个实体表的主键,才能表示它们之间的关系,那么可以把这两个主键联合组成复合主键即可。如 果两个实体存在多个关系,可以再加一个顺序字段联合组成复合主键,但是这样就会引入业务主键的弊端。当然也可以另外对这个关系表添加一个逻辑主键,避免了 业务主键的弊端,同时也方便其他表对它的引用。

\r\n

\r\n    综合来说,网上大多数人是倾向于用逻辑主键的,而对于实体表用复合主键方式的应该没有多少人认同。支持业务主键的人通常有种误解,认为逻辑主键必须对用户来说有意义,其实逻辑主键只是系统内部使用的,对用户来说是无需知道的。

\r\n

\r\n 结论或推论:

\r\n

\r\n 1、尽量避免使用业务主键,尽量使用逻辑主键。

\r\n

\r\n 2、如果要使用业务主键必须保证业务主键相关的业务逻辑改变的概率为0,并且业务主键不太大,并且业务主键不能交由用户修改。

\r\n

\r\n 3、除关系表外,尽量不使用复合主键。

\r\n

\r\n 使用逻辑主键的最佳实践指南:

\r\n

\r\n 1、足够用就好。系统使用的生命周期以100年为限,逻辑主键数据类型采用下表规则,如果不确定则使用int类型。

\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n

\r\n 数据量

\r\n
\r\n

\r\n 数据类型

\r\n
\r\n

\r\n 数据大小

\r\n
\r\n

\r\n 生成频率

\r\n
\r\n

\r\n 备注

\r\n
\r\n

\r\n < 128

\r\n
\r\n

\r\n tinyint

\r\n
\r\n

\r\n 1 字节

\r\n
\r\n

\r\n 1条/年

\r\n
\r\n

\r\n 频率过低,不太靠谱,不建议采用

\r\n
\r\n

\r\n < 3 万

\r\n
\r\n

\r\n smallint

\r\n
\r\n

\r\n 2 字节

\r\n
\r\n

\r\n 27条/月

\r\n
\r\n

\r\n 频率较低,慎用

\r\n
\r\n

\r\n < 21 亿

\r\n
\r\n

\r\n int

\r\n
\r\n

\r\n 4 字节

\r\n
\r\n

\r\n 40条/分钟

\r\n
\r\n

\r\n 能满足大部分情况

\r\n
\r\n

\r\n < 922 亿亿

\r\n
\r\n

\r\n bigint

\r\n
\r\n

\r\n 8 字节

\r\n
\r\n

\r\n 292万条/毫秒

\r\n
\r\n

\r\n 能满足绝大部分情况 

\r\n
\r\n

\r\n >= 922 亿亿

\r\n
\r\n

\r\n uniqueidentifier

\r\n
\r\n

\r\n 16 字节

\r\n
\r\n

\r\n 100亿用户同时每毫秒生成10亿条,可以连续生成10亿年

\r\n
\r\n

\r\n 可用于分布式、高并发的应用

\r\n
\r\n

\r\n 2、一般采用自增长方式或NewID()方式。

\r\n

\r\n 3、主键字段名称一般采用“表名ID”方式,方便识别和表联接。

\r\n

\r\n 4、如果表存在分布式应用,则可以考虑采用不同起始值,相同步长方式自增。例如有3个部署在不同地方的库,则可以如下设计:

\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n

\r\n 起始值

\r\n
\r\n

\r\n 步长

\r\n
\r\n

\r\n 1

\r\n
\r\n

\r\n 10

\r\n
\r\n

\r\n 2

\r\n
\r\n

\r\n 10

\r\n
\r\n

\r\n 3

\r\n
\r\n

\r\n 10

\r\n
\r\n

\r\n 步长统一设置10是为了方便日后扩展,这样不同库之间也能保持主键唯一性了,也方便合并。

\r\n

\r\n 5、如果存在高并发性需求或数据表迁移需求,可以考虑使用uniqueidentifier类型,并使用NewID()函数。

\r\n

\r\n 6、可以考虑对业务主键建立唯一性索引,以实现业务主键唯一性的业务需求。

\r\n

\r\n 7、如果需要考虑业务主键的性能需求,可以把业务主键建立聚集索引,而逻辑主键只建立主键约束和非聚集索引即可。

\r\n

\r\n 8、关系表可以考虑采用复合主键方式,复合主键不用于实体表。

\r\n

\r\n  

\r\n

\r\n 参考文献:

\r\n

\r\n 关系数据库主键分析
\r\n Hibernate开发与实战
\r\n 数据库主键设计之思考
\r\n [讨论]业务主键 Vs. 逻辑主键,到底哪个好?
\r\n 逻辑主键和联合主键,一定要讨论清楚!
\r\n 关于在表中设主键的问题
\r\n 关于在表中设主键的问题

\r\n
\r\n

\r\n
\r\n
\r\n  

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2816, '1637', '20131215044541', '2012-11-05 23:46:06', '2019-03-25 21:29:22', '

\r\n 1.创新的前提是模仿。没有人生来就高手,创新只不过是大量经验积累之后的优化重组,再加上一点灵感闪现。但灵感的闪现绝不是偶然的,没有大量的积累,不可能有灵感之源,厚积薄发,量变才能到质变。(2012/11/5)
\r\n 2.

\r\n 更新中。。。

\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2817, 'dedecms-description-of-the-system-security-features', 'DedeCMS系统安全检测功能使用说明', '2012-11-05 23:14:19', '2019-03-25 21:29:22', '

\r\n  这个月织梦官方加强了dedecms安装设置的引导,大家在登陆dedecms5.7后台的时候,会看到DedeCMS安全提示,通过安全提示, 大家可以对网站目录权限进行全面检测,根据织梦官方给出的目录权限设置,对自身网站目录权限进行设置,以应对日益严峻的网络安全形势,这篇文章对安全检测 功能进行详细说明,让用户更加容易了解如何设置使用。对于安全设置有疑问的地方也可以到织梦官方论坛进行反馈。

\r\n

\r\n   1.系统后台首页安全状态提示

\r\n

\r\n   我们登录系统后台,能够直接显示目前系统的安全状态(如图1):

\r\n

\r\n \"\"

\r\n

\r\n   根据安全状态提示我们可以进行系统安全设置。

\r\n

\r\n   注意:
\r\n   系统安全提示会一直存在,直到系统安全设定全部正常。

\r\n

\r\n   2.系统安全提示说明
\r\n   2.1.目录权限检测

\r\n

\r\n   DedeCMS系统运行对系统目录的权限是有非常严格的需求的,用户需要按照安全设置对自己的站点目录权限 进行配置,同时在更新中我们加入了安全检测工具。点击后台系统首页提示中的“全面检测”,或者展开首页面板中的“系统信息”,点击“DedeCMS目录权 限检测工具”,来进行权限检测(如图2)。

\r\n

\r\n \"\"

\r\n

\r\n   这里分别对DedeCMS系统涉及到的站点目录中执行、读取、写入权限进行检测,尤其是执行权限,是安全设置中的重要环节,具体配置可以参看:《如何取消服务器/主机空间目录脚本的执行权限》。

\r\n

\r\n   2.2.默认管理目录更名
\r\n   系统安装完毕,需要将默认dede目录更改为其他名称,更改的名称复杂度越高越安全。

\r\n

\r\n   2.3.默认管理员账号密码修改
\r\n   系统默认用户名admin,建议用户在安装使用时候将其更名,密码复杂度也是越高越好。

\r\n

\r\n   2.4.将data目录移到Web目录以外
\r\n   如果是独立主机或者VPS的用户,强烈建议按照说明将data目录移到Web目录以外的文件夹中,以防止被恶意利用。具体参看《如何将系统的data目录迁移到web以外目录 》。

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2818, 'free-dedecms-qq-login-plugin-for-v5-5-v5-6-v5-7', '免费DedeCMS版QQ登陆插件FOR V5.5 V5.6 V5.7', '2012-11-05 23:08:44', '2019-03-25 21:29:22', '

\r\n 使用说明:
\r\n   此插件是方便会员进行注册登录操作,为站长带来更多活跃会员

\r\n

\r\n   使用此插件要注意一下几点:

\r\n

\r\n   1、此插件使用前请到 http://connect.opensns.qq.com申请appid, appkey, 并注册callback地址
\r\n   2、配置完成参数,复制下面的代码,添加到你需要的页面,路径位置根据需要做相应改动
\r\n   3、请将回调参数修改成www.xxx.com改成你的域名(如:www.yiqiu.org)用于接收腾讯接口返回的参数
\r\n   4、此插件为亦秋工作室开发,站长可以免费使用,请保留我们的版权!
\r\n   5、修改用户名长度限制,打开reg_new.php文件,第67行“if(strlen($userid) > 20 || strlen($uname) > 36)”代码改成“if(strlen($userid) > 40 || strlen($uname) > 36)”限制长度,站长可以自行修改
\r\n   6、示例网站:http://www.yingsheji.com

\r\n
\r\n

\r\n 下载:qqLogin.zip

\r\n
\r\n

\r\n   转自:http://www.yiqiu.org/yqxw/2012/0529/19.html

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2819, 'helps-improve-the-speed-of-weaving-dreams-dedecms-html-generated-dede-block-plugin', '有助于提升织梦DedeCMS HTML生成速度的DEDE区块插件', '2012-11-05 23:01:58', '2019-03-25 21:29:22', '

\r\n 最近接手一个DEDE项目, 一开始文章不是很多的时候生成整站还行,随着每天几百篇文章的增加导致更新一次文章页面需要半个小时左右,能否有局部的方案。

\r\n

\r\n 如是乎做了一个 DEDE  中能生成页面块以便其他页面能 SSI (Server Side Include)包含的插件、方便模板调用。

\r\n

\r\n 次插件功能:区块分类、代码类区块、模板型区块、单一生成区块、批量生成区块等;

\r\n

\r\n 使用环境:大量页面的局部更新,或者批量更新广告代码,其他;

\r\n

\r\n 使用本插件: 请确保您的服务器开启 SSI 

\r\n
    \r\n
  • \r\n Apache 开启ssi
  • \r\n
\r\n

\r\n Apache默认是不支持SSI的,需要我们更改httpd.conf来进行配置。我这里以windows平台的Apache 2.0.x为例,打开conf目录下的httpd.conf文件,搜索“AddType text/html .shtml”,找到:

\r\n

\r\n   AddType text/html .shtml 
\r\n   AddOutputFilter INCLUDES .shtml 
\r\n 把这两行前面的#去掉 。

\r\n

\r\n 然后搜索“Options Indexes FollowSymLinks
\r\n 在搜索到的那一行后面添加“ Includes
\r\n 即将该行改变为 Options Indexes FollowSymLinks Includes
\r\n 熟悉apache manual的可能会觉得比较容易。
\r\n 保存httpd.conf,重起apache即可
\r\n 到此我们就完成了对Apache SSI的设置。

\r\n
    \r\n
  • \r\n IIS开启 ssi
  • \r\n
\r\n

\r\n \"\"

\r\n
    \r\n
  • \r\n NGINX 开启 SSI
  • \r\n
\r\n

\r\n 主要是三个参数,ssi,ssi_silent_errors和ssi_types,均可以放在http,server和location的作用域下。

\r\n

\r\n ssi on
\r\n 开启ssi支持,默认是off

\r\n

\r\n ssi_silent_errors on
\r\n 默认值是off,开启后在处理SSI文件出错时不输出错误提示:”[an error occurred while processing the directive] ”

\r\n

\r\n ssi_types
\r\n 默认是ssi_types text/html,所以如果需要htm和html支持,则不需要设置这句,如果需要shtml支持,则需要设置:ssi_types text/shtml

\r\n

\r\n 确保你的服务器开启SSI 后安装插件即可。

\r\n

\r\n 安装后:

\r\n

\r\n \"\"

\r\n

\r\n 点击增加区块

\r\n

\r\n \"\"

\r\n

\r\n 点击 保存区块 添加友情链接区块 回到列表页面点击更新即可更新次区块,查看代码点击 红色名称。也可复制区块。

\r\n

\r\n \"\"

\r\n

\r\n 批量生成文件名称必须包含 {id}  ({id}代码栏目编号)

\r\n

\r\n 点击 [] ,生成/更新HTML文件即可

\r\n

\r\n  \"\"

\r\n
\r\n

\r\n 下载地址:section.zip
\r\n 作者:warfu    QQ:4376285   有特殊功能需求的可联系本人二次开发.

\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2820, 'weaving-dreams-dedecms-article-list-pages-automatically-and-statistics-of-the-current-total-number-of-program-documents', '织梦DedeCMS文章列表页自动统计当前栏目文档总数的方法', '2012-11-05 22:05:22', '2019-03-25 21:29:22', '

\r\n     可以通过该方法在列表页内显示该栏目共有多少篇文章,有助于提升用户体验。比如说我一个文章列表下面有10篇文章,就自动统计出10篇,到20篇的时候自动统计成20篇。

\r\n

\r\n   实现这个功能有两种具体的方法:

\r\n

\r\n   第一种:runphp=’yes’

\r\n

\r\n   利用织梦自带的runphp参数来实现这个功能,只需要在您需要显示统计数量的地方直接加入以下代码:
\r\n  

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n{dede:field.typeid runphp='yes'}\r\n    global $dsql;\r\n    $row = $dsql->GetOne("select count(*) as dd from dede_archives where typeid = @me");\r\n    @me = $row['dd'];\r\n {/dede:field.typeid}
\r\n
\r\n

\r\n 第二种:function

\r\n

\r\n   我们通常所说的函数,在织梦(DedeCMS)中,我们可以利用自定义函数来实现各种效果,实现的具体方法为:

\r\n

\r\n   在/include/extend.func.php文件的?>上一行加入以下代码:
\r\n  

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\nfunction _GetTypeNum($tid){\r\n    global $dsql;\r\n    $row = $dsql->GetOne("select count(*) as dd from dede_archives where typeid = $tid");\r\n    return $row['dd'];\r\n}
\r\n
\r\n

\r\n  在模板需求统计栏目文档的地方加入以下代码:

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n{dede:field.typeid function="GetTypeNum(@me)"/}
\r\n
\r\n

\r\n 注意事项:

\r\n

\r\n   1、本代码无法统计副栏目的文档;
\r\n   2、本代码可用在列表和内容页;
\r\n   3、代码生成后的效果的动态的,如果添加完内容,必须重新生成相关页面;
\r\n   4、无法统计无主表(例如:分类信息)的文档总数;

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2839, '10-reasons-to-install-office-2010-trial', '安装试用Office 2010 的 10 大理由', '2012-11-06 02:59:50', '2019-03-25 21:29:22', '

\r\n 1、更直观地表达您的创意。  
\r\n
\r\n   Office 2010 开创了设计选项的时代,这些设计选项可以帮助您通过更具视觉冲击力的形式表达您的创意。新增和改进的图片格式工具(如颜色饱和度和艺术效果)使您可以增加 视觉图形的艺术性。大量新增的可自定义主题和 SmartArtreg; 图形布局提供了用于使您的创意形象生动的更多方法。

\r\n
\r\n

\r\n \"安装试用Office

\r\n
\r\n

\r\n  
\r\n
\r\n   2、通过协同工作完成更多任务。  
\r\n
\r\n   以团队形式进行协作可以集思广益、使版本保持同步状态和更快地完成任务。Word 2010、PowerPoint 2010、Excel Web App 和 OneNote 2010 共享笔记本中的共同创作功能允许您与其他用户同时编辑同一文件,即使这些用户位于不同的位置也是如此。

\r\n
\r\n

\r\n \"安装试用Office

\r\n
\r\n

\r\n   
\r\n
\r\n   3、从更多位置和设备享受熟悉的 Office 体验。  
\r\n
\r\n   通过 Office 2010,可以按照日程表完成任务。  
\r\n
\r\n   Microsoft Office Web Apps。将 Office 2010 体验扩展到 Web 上。联机存储 Word、Excel、PowerPoint 和 OneNote 文件,然后几乎可以从任意位置访问、查看、编辑和共享内容。  
\r\n
\r\n   Microsoft Office Mobile 2010。使用专门为 Windows 电话设计的 Office 2010 应用程序的新移动版本掌握最新信息并快速做出响应。  
\r\n
\r\n   Microsoft SharePoint Workspace 2010。将 SharePoint 2010 列表和库与 SharePoint Workspace(以前称为 Microsoft Office Groove)同步,以便您可以从您的计算机随时随地访问、查看和编辑文件。恢复联机状态后所有内容都将自动同步到 SharePoint 服务器。
\r\n
\r\n   4、保持与商业和社交网络的联系。  
\r\n
\r\n   通过 Outlook 2010 可以与同事、客户和朋友保持联系。使用 Outlook Social Connector 可以快速查看从个人收到的电子邮件、会议或附件的历史记录。获取人员的其他信息以通过 SharePoint My Site、Windows Live 或其他常见第三方网站掌握商业和社交圈的信息。  
\r\n
\r\n   5、即时传播信息。  
\r\n
\r\n   向远程观众广播 PowerPoint 演示文稿,不管他们是否安装了 PowerPoint。4新增的 PowerPoint 广播幻灯片功能允许您直接从办公桌进行演示,同时观众在 Web 浏览器中实时查看演示文稿。

\r\n
\r\n

\r\n \"安装试用Office

\r\n
\r\n

\r\n 6、创建有影响力的数据观点。  
\r\n
\r\n   利用 Excel 2010 中新增的数据分析和可视化功能,可以跟踪并突出显示重要数据趋势。新增的迷你图功能可将清晰、简洁的数据直观表示通过工作表单元格中小图表的形式发布。通 过切片器可以对数据透视表数据进行多个图层的筛选和分段,这样就可以在分析上多花些时间,而在格式设置上少花些时间。  

\r\n
\r\n

\r\n \"安装试用Office

\r\n
\r\n

\r\n
\r\n   7、轻松管理大量电子邮件。  
\r\n
\r\n   通过组织收件箱节省宝贵的时间。Outlook 2010 允许您将大量电子邮件压缩到几个可分类、设置优先级和方便归档的对话中。通过新增的快速步骤功能,您只需单击一次即可执行多命令任务,如答复并删除。  
\r\n
\r\n   8、交付引人入胜的演示文稿。  
\r\n
\r\n   通过演示文稿中的个性化视频吸引访问群体。在 PowerPoint 2010 中直接嵌入和编辑视频。剪裁关键场景、为其添加淡化效果或为其创建书签。现在,默认情况下会嵌入从文件中插入的视频,以便您可以共享动态演示文稿,而不必管理单独的媒体文件。

\r\n
\r\n

\r\n \"安装试用Office

\r\n
\r\n

\r\n   
\r\n
\r\n   9、将所有创意存储在一个位置并进行跟踪。  
\r\n
\r\n   利用 OneNote 2010,您可以获取最终数字笔记本,用于跟踪、组织和共享文本、图片、音频和视频文件。一些新增功能(如页面版本跟踪、自动突出显示和链接笔记)可让您更好地控制信息,这样,您就始终可以掌握您的内容和其他人所做的更改。  
\r\n
\r\n   10、按照您的方式更加快速、轻松地工作。  
\r\n
\r\n   Microsoft Office Backstage&#8482; 视图取代了传统的“文件”菜单,通过该视图可以集中执行所有文件管理任务,包括保存、共享、打印和发布。增强的功能区在 Office 2010 应用程序中均可用,允许您快速访问命令,以及创建或自定义选项卡以适合自己的工作方式。
\r\n   

\r\n
\r\n

\r\n \"安装试用Office

\r\n
\r\n

\r\n
\r\n   1 Word 2010、PowerPoint 2010、Excel Web App 和 OneNote Web App 的共同创作功能以及与计算机网络外部的其他用户共享的 OneNote 2010 笔记本的共同创作功能需要 SharePoint Foundation 2010(对于企业)或免费的 Windows Live ID(对于个人)。  
\r\n
\r\n   2 Office Web Apps 需要 SharePoint Foundation 2010(对于企业)或免费的 Windows Live ID(对于个人),以及适当的设备、Internet 连接和受支持的 Internet Explorer、Firefox 或 Safari 浏览器。  
\r\n
\r\n   3 需要适当的设备。Office Mobile 2010 未包含在 Office 2010 应用程序、套件或 Web Apps 中。Office Web Apps、Office Mobile 2010 和 Office 2010 应用程序的功能之间存在一些差异。 
\r\n
\r\n   4 PowerPoint 广播幻灯片需要 SharePoint Foundation 2010 或 Windows Live 帐户。若要通过 SharePoint 2010 广播,必须安装 Office Web Apps。

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2840, '%e4%bb%80%e4%b9%88%e6%98%af%e7%bd%91%e5%85%b3', '什么是网关', '2012-11-06 02:46:50', '2019-03-25 21:29:22', '

\r\n    顾名思义,网关(Gateway)就是一个网络连接到另一个网络的“关口”
\r\n   按照不同的分类标准,网关也有很多种。TCP/IP协议里的网关是最常用的,在这里我们
\r\n 所讲的“网关”均指TCP/IP协议下的网关。
\r\n   那么网关到底是什么呢?网关实质上是一个网络通向其他网络的IP地址。比如有网络A和网络B,网络A的IP地址范围为 “192.168.1.1~192. 168.1.254”,子网掩码为255.255.255.0;网络B的IP地址范围为“192.168.2.1~192.168.2.254”,子网掩 码为255.255.255.0。在没有路由器的情况下,两个网络之间是不能进行TCP/IP通信的,即使是两个网络连接在同一台交换机(或集线器) 上,TCP/IP协议也会根据子网掩码(255.255.255.0)判定两个网络中的主机处在不同的网络里。而要实现这两个网络之间的通信,则必须通过 网关。如果网络A中的主机发现数据包的目的主机不在本地网络中,就把数据包转发给它自己的网关,再由网关转发给网络B的网关,网络B的网关再转发给网络B 的某个主机(如附图所示)。网络B向网络A转发数据包的过程也是如此。所以说,只有设置好网关的IP地址,TCP/IP协议才能实现不同网络之间的相互通 信。那么这个IP地址是哪台机器的IP地址呢?网关的IP地址是具有路由功能的设备的IP地址,具有路由功能的设备有路由器、启用了路由协议的服务器(实 质上相当于一台路由器)、代理服务器(也相当于一台路由器)。

\r\n

\r\n 什么是默认网关
\r\n   如果搞清了什么是网关,默认网关也就好理解了。就好像一个房间可以有多扇门一样,
\r\n 一台主机可以有多个网关。默认网关的意思是一台主机如果找不到可用的网关,就把数据包发给默认指定的网关,由这个网关来处理数据包。现在主机使用的网关,一般指的是默认网关。

\r\n

\r\n 如何设置默认网关
\r\n   一台电脑的默认网关是不可以随随便便指定的,必须正确地指定,否则一台电脑就会将
\r\n 数据包发给不是网关的电脑,从而无法与其他网络的电脑通信。默认网关的设定有手动设置和自动设置两种方式。
\r\n   1. 手动设置
\r\n   手动设置适用于电脑数量比较少、TCP/IP参数基本不变的情况,比如只有几台到十几台
\r\n 电脑。因为这种方法需要在联入网络的每台电脑上设置“默认网关”,非常费劲,一旦因为迁移等原因导致必须修改默认网关的IP地址,就会给网管带来很大的麻烦,所以不推荐使用。
\r\n   在Windows 9x中,设置默认网关的方法是在“网上邻居”上右击,在弹出的菜单中点击
\r\n “属性”,在网络属性对话框中选择“TCP/IP协议”,点击“属性”,在“默认网关”选项卡中填写新的默认网关的IP地址就可以了。
\r\n   需要特别注意的是:默认网关必须是电脑自己所在的网段中的IP地址,而不能填写其他
\r\n 网段中的IP地址。
\r\n   2. 自动设置
\r\n   自动设置就是利用DHCP服务器来自动给网络中的电脑分配IP地址、子网掩码和默认网关
\r\n 。这样做的好处是一旦网络的默认网关发生了变化时,只要更改了DHCP服务器中默认网关的设置,那么网络中所有的电脑均获得了新的默认网关的IP地址。这种方法适用于网络规模较大、TCP/IP参数有可能变动的网络。
\r\n   另外一种自动获得网关的办法是通过安装代理服务器软件(如MS Proxy)的客户端程序
\r\n 来自动获得,其原理和方法和DHCP有相似之处。由于篇幅所限,就不再详述了。

\r\n

\r\n    如果开始看路由知识的话,就会容易明白了,

\r\n

\r\n 进入命令行模式:

\r\n

\r\n c:>;route print
\r\n 会有一条路由:
\r\n 0.0.0.0 0.0.0.0 默认网关的IP 接口(机器的IP) 跳数
\r\n 比如我的机器:

\r\n \"\"

\r\n

\r\n 意思是:所有的需要转发的数据包,都经过默认网关的IP(接口)发送出去,当然返回也是从那里经过。

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2841, 'windows-registry-details', 'Windows注册表详解', '2012-11-06 00:29:38', '2019-03-25 21:29:22', '

\r\n    注册表,Windows中最强大的工具。如果说Windows图形界面是井,应用程序的运行是水,那么注册表就是我们取水的桶,没有注册表这个“桶”,大多数程序就只能看不能用。对它简单地改动都能让你单击某个程序却不能运行,让你的各种运行奇慢无比,在你的各种状态栏留下各种无聊的信息。注册表听起来很高深,其实挺简单。它就像是你的文件夹一样,有根目录有子目录,根目录表示主要的功能,子目录将这些主要功能再细化,最后落实到键值就相当于最后子目录中的运行程序。每个键值就一个功能,而我们只需要知道某项功能可能在哪些主目录、哪些子目录,最后在其中找到可能的键值就可以了。这样,你就能自己探索注册表的奥秘了。
\r\n
\r\n 注册表历史
\r\n
\r\n    在DOS时代,我们所有的硬件设备都是通过启动盘下的Confis.sys和 Autoexec.bat两个配置文件在系统启动时加载驱动程序并使其工作的(现在Windows中也部分保留这种配置方式),而到了后来的 Windows 3.x,则通过Win.ini、System.ini、Control.ini、program.ini等INI文件来保存所有有关操作系统和应用程序的配置信息。但出于安全的考虑(任何文本编辑工具都能修改ini文件,而且ini文件可读性很强)以及越来越多的相关信息需要储存,使得微软从Windows  95开始将注册表概念引入到操作系统中来。
\r\n 注册表就是一个统一集中地管理系统硬件设施、软件配置等信息的数据库,其中存放着各种参数,直接控制着windows的启动、硬件驱动程序的装载以及一些Windows应用程序的运行,并在其中记录了与机器有关的硬件和软件的配置信息,及联网计算机的整个系统的设置和各种许可,文件扩展名与应用程序的关联,硬件部件的描述、状态和属性,性能记录和其他底层的系统状态信息,以及其他数据等。
\r\n    当然注册表这个数据库是不能用其他编辑软件打开的,他被存放在Windows文件夹下的system.datuser.dat两个隐藏文件中,在Windows中你只有用“运行”命令行regedit才能进行编辑,当然你也可以用编辑软件创建.reg来修改。 
\r\n
\r\n 注册表的结构
\r\n
\r\n    注册表的信息当然不会杂乱无章地排列,虽然它被存放在System.dat和User.dat两个二进制文件中,但是它内部的组织结构是一个类似于文件夹管理的树状分层的结构。当然他们没有主目录、子目录的称号,他们有自己的名字主键、子键、键值名称及键值数据。
\r\n    Windows注册表的主键(相当于主目录)主要包括HKEY_LOCAL_MACHINEHKEY_USERS HKEY_CURRENT_USER、  HKEY_CLASSES_ROOTHKEY_CURRENT_CONFIGHKEY_DYN_DATA六大主键,这六大主键在所有的Windows操作系统中是固定不便的,其中最为主要的是HKEY_LOCAL_MACHINE和HKEY_USERS两大主键,它们是注册表的核心HKEY_LOCAL_MACHINE对应着System.dat文件,而HKEY_USERS则对应着User.dat文件
\r\n
\r\n 注册表使用详解
\r\n
\r\n    因为Windows注册中就是由六大主键组成的,因此我们也按照六大主键的结构来详细讲解注册表。
\r\n 1、HKEY_CLASSES_ROOT
\r\n    打开这个主键,你会发现很多以.c、.doc、.dll等为名字的子键。其实很简单,它是HKEY_LOCAL_MACHINESoftwareClasses下的一个快捷方式,大家同样可以到HKEY_LOCAL_MACHINE SoftwareClasses下进行操作。在它的主键里记录的是系统中各类文件与其应用程序之间的关联关系,因为它包括了成千上万的与程序、文件相 关联的键和值以及ActiveX类的储存等内容,而使得它成为注册表的一个最大分支。
\r\n    提示:相信大家对Windows中的关联一定不会陌生,我们 在资源管理器中双击系统中的某个文件时,系统会自动打开一个程序并会打开它。如双击一个Word文件则会自动调用Microsoft Word,而双击 BMP则会自动调用画图程序等等,这就是关联。而大家所不知道的是,其实当我们双击一文件后,Windows会首先在该主键下查找该类文件的扩展名,然后 以此扩展名子键中的文件类型信息为基础,再查找该类文件相对应的应用程序信息,最后使用相应的程序来打开我们双击的文件。如我们可以单击“开始”→“程 序”→“运行”命令,然后输入“regedit”来启动系统注册表,并单击HKEY_CLASSES_ROOT主键,找到“.bmp”子键,我 们会发现其记录其默认值为“Microsoft Word文档e”,而它的shell-open-command子键则记录的command子键的默认值 “C:WINDOWSSYSTEM32MSPAINT.EXE %1”,则表示它是调用C:WINDOWSSYSTEM32 MSPAINT.EXE程序来打开我们双击的BMP文件的。
\r\n    HKEY_CLASSES_ROOT主键下的子键很简单,主要包括两类,一类是文件 扩展名子键,另一类是文件类型子键。文件扩展名子键主要包括系统内定的文件扩展名和应用程序自储存的扩展名,文件扩展名子键均以“.”开头,后跟文件扩展 名,可以包括任意多个字符;“*”子键和其他的不以“.”开头的子键是类储存子键,其中包括文件类型、类标识符以及程序标识符。文件名扩展子键中指明了该 类文件的关联文件类型以及打开方式等。
\r\n    HKEY_CLASSES_ROOT主键中的文件类型子键下的常见子键的含义:
\r\n Defaulticon:默认的该类文件的显示图标,即我们在文件夹中看到的图标。
\r\n Shell:程序外壳子键
\r\n Shellopencommand:打开该类文件的外壳程序,默认值为相应程序的路径、名称及其参数
\r\n Shelleditcommand:编辑该类文件的外壳程序,默认值为相应程序的路径、名称及其参数
\r\n Shellprintcommand:打印该类文件的外壳程序,默认值为相应程序的路径、名称及其参数
\r\n HKEY_CLASSES_ROOT主键下还有一个重要的子键“CLSID”,该子键下记录了所有的已注册的系统类标识符。
\r\n 2、HKEY_USERS
\r\n  该主键下记录的是Windows中所有用户的设置信息,它的值是变化的,并取决于计算机是否激活了用户配置文件,若未激活用户配置文件,则可以看到称 为.DEFAULT的单一子键,该子键包括和所有用户相关的各种设置,并且和Windows下的USER.DAT文件相配合。若激活了用户配置文件并且 正确地执行了登录,则还有一个“用户名”的子键,该用户名为用户登录的名称。而有关该用户名的相关键值则放在HKEY_CURRENT_USER中。
\r\n 3、HKEY_CURRENT_USER
\r\n    在HKEY_CURRENT_USER主键中保存了当前登录用户的所有配置信息,它也是自动变化的,取决于当前登录的用户,它其实就是 HKEY_USERS用户名键下的快捷方式,当然了,如果我们的机器未激活用户配置则它是HKEY_USERS.DEFAULT的快捷方式。
\r\n    在该主键下有8个子键,它们的作用分别是:
\r\n (1)AppEvents
\r\n 该子键储存了系统事件的声音设置。在下面还 有“EventLabels”和“Schemes”两个子键。子键 EventLabels-储存了每个事件的标识及名称,而子键Schems则关联了每 个事件和声音,下边有“Apps”和“Name”两个子键,“Apps”子键下储存了系统事件的声音设定,一般每个事件下有两个子键“.Current” 和“.Default”,它们分别指明了当前的声音文件和默认的声音文件的位置。“Name”子键储存了声音配音方案的名称,该名称我们也可以在控制面板 中双击“声音”项,然后在出现的声音属性窗口中的方案选项中看到。
\r\n (2)Control Panel
\r\n    该子键储存了系统桌面、光标、图标、键盘鼠标等的设置信息。其下一般下面的子键:
\r\n “Accessibility”: 一看就知道,它只有在安装了Windows系统辅助选项后才会出现,其中包括了高对比度显示设置子键“HighContrast”、键盘设置子键 “KeyboardResponse”、鼠标设置子键“MouseKeys”、串行键设置子键“SerialKeys”、声音显示设置子键 “ShowSounds”、声音卫士设置子键“SoundSentry”、粘滞键设置子键“StickyKeys”、自动重新设置辅助选项子键 “TimeOut”和切换键设置子键“ToggleKeys”,它们都是辅助选项中的设置信息。
\r\n “Appearance”:该子键储存了系统中可供选择的各种颜色设置方案,我们可以在显示属性窗口中的“外观”选项卡中看到相应的方案。
\r\n “Cursors”:该子键储存了系统中使用的光标图案,我们可以在鼠标属性窗口中的指针页的方案选项中看到。
\r\n “Desktop”: 该子键储存了系统桌面和窗口的设置信息,如窗口边界、标题、图标、菜单、滚动条等的设置。其下键值很多,大家在看了它的英文名称后便知道了。另外,在 Desktop子键下包括“ResourceLocale”和“WindowMetrics”两个子键,“ResourceLocal”子键储存了桌面数 据的显示格式的时区值;“WindowsMetrics”储存了系统窗口的各项设置,这些看起来也不困难。笔者就不再赘述了。
\r\n “Input Method”:该子键储存了输入法切换键的有关设置,其中的键值“Show Status”确定是否显示输入法状态。
\r\n “International”:该子键储存了区域设置的有关信息。
\r\n “Keyboard”:该子键储存了键盘击键的重复延时和重复速率。
\r\n “PowerCfg”:该子键储存了电源管理的有关设置。
\r\n (3)Identities
\r\n    该子键存储并储存了和Outlook Express有关的设置信息。
\r\n (4)InstallLocationsMRU
\r\n    包括安装软件或硬件设备驱动程序的路径等,每个键值代表一个路径,其键值名称为一个小写的字母,如“a”、“d”等,键值“MRUList”表示了一个路径的顺序,如“daebc”。
\r\n (5)Keyboard layout
\r\n    该子键储存了Windows中键盘布局设置。
\r\n (6)Network
\r\n    该子键储存了当前用户的网络设置信息。
\r\n (7)RemoteAccess
\r\n    该子键储存了当前用户的拨号网络配置。
\r\n (8)Software
\r\n    该子键储存了系统中各种软件的配置信息,它是HKEY_CURRENT_USER主键下最主要的子键,也是USER.DAT文件的主要部分,该主键下的子键随着不同的机器会差别很大,但无论怎样不同,该主键下的子键都有着基本相同的结构。
\r\n 4、HKEY_LOCAL_MACHINE
\r\n HKEY_LOCAL_MACHINE上注册表的核心主键,记录了计算机上的所有硬件和软件的配置。它由8个部分组成,而每部分中又有许多相应的子键。
\r\n (1)Config键
\r\n 在 该键值中储存了Windows配置文件,它下面的子键个数视机器而定,如 0001,0002等等,每一个子键均代表一个硬件配置文件。在每一个子键下面有Display,Enum,Infrared,Software和System子键。其中Enum键包括安装在机器上的每种设备的配置数据,其内容随不 同的机器也不同,它对应多个子键:
\r\n   ⑴、BIOS:包括多种集成在主板上的设备,每个设备是一种EISA的格式(如 *PNP0001)。Microsoft分配一定的范围给某些设备类型,这些用户一般不必过问,因此我们略过,如果大家需要这方面的资料,可以上网查找。
\r\n   ⑵ESDI:指示硬盘类型及驱动器字符等。
\r\n     ⑶FLOP:指示软盘驱动器。
\r\n     ⑷HTREE:不包括任何设备,其下的RESERVER子键保留了保存在设备管理中的资源列表。
\r\n     ⑸ISAPNP:ISA即插即用设备。
\r\n     ⑹INFRARED: 红外线接口,可以看到每一个连接到这个端口上的虚拟设备的子键。
\r\n     ⑺LPTENUM: 只有在并口上安装了即插即用的打印机时才存在。
\r\n     ⑻MF: 包括每个安装在计算机中的每个多功能设备的子键。
\r\n     ⑼MONITOR: 常包括一个单一的子键 .DEFAULT_MONITOR,指示当前的显示器。
\r\n     ⑽NetWork: 网络协议,通常可以看到如下子键:FASTIR-红外线协议,MSTCP-TCPIP,VREDIR-MicroSoft网络客户,VSERVER-文件和打印机共享
\r\n     ⑾PCI: 包括每个PCI设备。
\r\n     ⑿PCMCIA:安装在计算机上的PC CARD设备。
\r\n     ⒀ROOT: 计算机检测出的或通过“添加新硬件”而未正确安装驱动程序的硬件。
\r\n    ⒁SCSI: 安装在计算机上的每个SCSI设备。
\r\n     ⒂SERENUM: 连接到串行接口上的设备。
\r\n     ⒃USB: 连接到USB接口上的设备。
\r\n     ⒄VPOWERD: 电源管理。
\r\n (2)HARDWARE键
\r\n 在该键值中储存了计算机硬件配置中的一些不确定的信息。
\r\n (3)NetWork键
\r\n 该键值储存了包括安全提供者和当前的用户名及组策略等。
\r\n (4)Security键
\r\n 该键值储存了具有管理权限的每个用户和组等信息。
\r\n (5)Software键
\r\n 安装在计算机中的软件的设置。每个软件程序统一使用“公司名称软件名称软件版本”的组织形式,本部分的设置对于排除故障和定制系统很有用。
\r\n (6)System键
\r\n 该键值储存了系统中的设备驱动程序等信息。
\r\n 5、HKEY_CURRENT_CONFIG
\r\n 是HKEY_LOCAL_MACHINEConfig的快捷方式。
\r\n 6、HKEY_DYN_DATA
\r\n 系统的动态数据。
\r\n
\r\n    了解了这些键的意义,你可以自己来研究了,出现什么问题找好主键和子键,改动改动。当然别忘了备份。其实,Windows每次启动都会自动对注册表进行备份,放在windowssysbckup里的rb00X.cab文件里,出注册表出现问题,在DOS下用extract /e展开,拷贝回去就可以了。 当然你可以直接将System.dat和User.dat拷出来做备份。

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2842, 'about-googles-go-language', '谈谈Google的Go语言', '2012-11-05 21:15:31', '2019-03-25 21:29:22', '
\r\n

\r\n \"\"

\r\n

\r\n 序言:关于Go

\r\n

\r\n    Go语言是一个开源、并发、高效、简单、有趣(但对某些人来说可能很无聊)的编程语言,支 持垃圾回收(GC),具有很好的可伸缩性。Go是从2007年末由Robert Griesemer, Rob Pike, Ken Thompson主持开发,后来还加入了Ian Lance Taylor, Russ Cox等人,并最终于2009年11月开源,在2012年早些时候发布了Go 1稳定版本。现在Go的开发已经是完全开放的,并且拥有一个活跃的社区。

\r\n

\r\n    Go最初是为了解决Google的问题而开发的,要知道Google面临着很多大问题。Google的中服务器最主要是C++编写的,除此之外还有 很多Java、Python代码。另外,Google还有数千名工程师、无数行代码、庞大的分布式构建系统以及数不清的机器(我们认为相对于一个中等规模 的集群)。Google的开发可能很慢,甚至笨拙,但它总是很有效。

\r\n

\r\n    所以毫无疑问Go对“大硬件”的支持非常好,也适合“大软件”的开发。CSDN之前也编译了一批Rob Pike的文章——Go语言之父谈Go:大道至简,在这里Rob描述了Go的创作起源和初衷。

\r\n

\r\n \"\"

\r\n

\r\n 为什么应该用Go?

\r\n

\r\n    Go是为了帮助人们阅读、调试和维护大型软件系统而生的,所以目标是
\r\n    (1)不再缓慢
\r\n    (2)不再笨拙
\r\n    (3)提高效率
\r\n    (4)保持(甚至提升)扩展性

\r\n

\r\n    但是在使用C++或者Java开发中却常常遇到各种问题:
\r\n    (1)构建缓慢
\r\n    (2)依赖性难以控制
\r\n    (3)每个编程语言都使用不同的语言子集
\r\n    (4)程序难以理解(文档等原因)
\r\n    (5)重复工作
\r\n    (6)更新成本高
\r\n    (7)版本交叉
\r\n    (8)自动化不方便(工具问题)
\r\n    (9)跨语言构建

\r\n

\r\n    而Go语言则是为了解决这些问题而设计的。

\r\n

\r\n    另外,C语言的依赖一直是个大问题,包括依赖叠加、编译时引入依赖的情况都很难处理,同时你也没办法查清哪些依赖是可以删除的,那些不可以。在C++中,这一点变得更加明显:
\r\n    (1)每个类里都有#include文件
\r\n    (2)#include文件中有代码(而不仅仅是声明)
\r\n    (3)#ifndef的残留

\r\n

\r\n    所以一直无法在一台机器上构建大型Google二进制。(To build a large Google binary on a single computer is impractical.)

\r\n

\r\n    当然,工具确实很有帮助,于是做了如下改进:
\r\n    (1)新的分布式构建系统
\r\n    (2)不再需要Makefile(但仍然使用BUILD文件)
\r\n    (3)多缓存
\r\n    (4)多复杂度(大程序本身所具有的)

\r\n

\r\n    即使在Google的分布式构建系统的的帮助下,大型构建工程依然会花费不少时间(以其中一个二进制文件为例,在2007年花了45分钟,现在是27分钟)。生活质量还是太低。

\r\n

\r\n 走进Go语言

\r\n

\r\n    我们都希望拥有更高质量的生活,所以必须解决这些问题,所以就有了最初的想法:
\r\n    (1)必须是可扩展的
\r\n    (2)适合大型程序、大型团队以及拥有大量依赖的应用
\r\n    (3)必须易于接近,例如接近C语言那样。
\r\n    (4)现代化
\r\n    (5)适合多核机器
\r\n    (6)适合网络机器
\r\n    (7)适合Web开发

\r\n

\r\n    Go语言的设计是以软件工程为目标,所以它有这些优点:
\r\n    (1)清晰的依赖
\r\n    (2)清晰的语法
\r\n    (3)清晰的语义学
\r\n    (4)简单的模型(垃圾回收和并发性)
\r\n    (5)便捷的工具(go tool、gofmt、godoc、gofix等)

\r\n

\r\n 还有那些问题?

\r\n

\r\n    Go语言目前所面临的最大问题在于,还没有足够的经验来证明Go是否真的是一个成功的产 品,缺少大型应用实践。但是在Google内部,如golang.org、youtube.com、dl.google.com都已经开始使用Go语言开 发,除此之外还有一些其它小应用(有的是在GAE上)也选择使用Go;而在Google之外,BBC Worldwide、Canonical、Heroku、Nokia、SoundCloud也都在尝试Go。

\r\n

\r\n    总而言之,Go是由软件工程驱动的编程语言,但富有成效并且有趣,这样的设计非常高产。

\r\n

\r\n    Rob Pike演讲的Slide可以在这里看到。

\r\n
\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2843, 'jdk1-6%e6%96%b0%e7%89%b9%e6%80%a7', 'JDK1.6新特性', '2012-10-30 23:23:58', '2019-03-25 21:29:22', '

\r\n    2006 年底,Sun 公司发布了 Java Standard Edition 6(Java SE 6)的最终正式版,代号 Mustang(野马)。Java 平台的第六个版本, Standard Edition (Java SE), 代号Mustang, 发布了第二个Beta版本.这一次,是时隔4个月发布第二次Beta版本.
\r\n
\r\n    Java SE 6 Beta 2 (Mustang) 有什么新东西? 有什么值得开发者关注?

\r\n

\r\n   1、简化Web Services

\r\n

\r\n   2、整合脚本语言

\r\n

\r\n   3、绑定Derby

\r\n

\r\n   4、更丰富的Desktop APIs

\r\n

\r\n   5、监视和管理

\r\n

\r\n   6、可插入式元数据

\r\n

\r\n   7、访问编译器

\r\n

\r\n   8、安全性
\r\n
\r\n 简化Web Services
\r\n    Mustang 将 简化Web services 的开发和发布. XML和Web服务一直都是Mustang的关注重点.. Mustang为此引入了JAX-WS(Java Architecture for XML-Web Services) 2.0 以及JAXB(Java Architecture for XML Binding) 2.0.. 同时还有Streaming API for XML (STaX), 它提供了一个双向API,这个API可以通过一个事件流来读取或者写入XML,其中包括跳过某个部分,然后直接关注与文档中的另外一个小部分的能力。
\r\n
\r\n Scripting,整合脚本语言
\r\n    目前来讲,Java 开发者们必须在Java之外独立地额外编码来使用non-Java 脚本语言。这个头痛的问题将被Mustang 消灭,开发者将更加轻松的使用Perl、PHP、Python、JavaScript 和Ruby等脚本语言。新的框架将允许人们操作任意的脚本语言,和使用Java 对象。
\r\n
\r\n    Java SE6中实现了JSR223。这是一个脚本框架,提供了让脚本语言来访问Java内部的方法。你可以在运行的时候找到脚本引擎,然后调用这个引擎去执行脚 本。这个脚本API允许你为脚本语言提供Java支持。另外,Web Scripting Framework允许脚本代码在任何的Servlet容器(例如Tomcat)中生成Web内容。
\r\n
\r\n Database,绑定Derby
\r\n 开源嵌入式数据库 Derby(JavaDB) 绑定在JDK 1.6中.具体可以参考:JDK 1.6 将绑定开源数据库 Derby
\r\n
\r\n 更丰富的Desktop APIs
\r\n Mustang中拥有更多强的桌面API提供给开发者, 开发者可以更简单地开发更强大的桌面应用, 比如启动界面的支持,系统托盘的支持,JTable排序等等
\r\n
\r\n 监视和管理
\r\n Java SE 6中对内存泄漏增强了分析以及诊断能力。当遇到java.lang.OutOfMemory异常的时候,可以得到一个完整的堆栈信息,并且当堆已经满了的 时候,会产生一个Log文件来记录这个致命错误。另外,JVM还添加了一个选项,允许你在堆满的时候运行脚本。(这也就是提供了另外一种方法来诊断错误)
\r\n
\r\n 增强的JMX
\r\n    监视API在MBean的属性值传入了一个特定的参数的时候,允许这个应用程序发送一个事件通告。(这里的属性值可以在很复杂的类型中)
\r\n
\r\n    对于Solaris 10的用户,为Solaris提供的Hotspot JVM中,提供了一种通过Solaris DTrace(这是个系统的调试工具)来追踪显示JVM内部的活动情况,包括垃圾收集,类装载,线程,锁等等。
\r\n
\r\n Pluggable Annotations
\r\n    从Java SE 5   带来得新特性Annotations,将在Mustang继续扮演重要角色..
\r\n
\r\n Compiler API:访问编译器
\r\n    对于Java开发工具, 或者Web框架 等的开发者来说, 利用编译器编译动态生成的代码, 是一个普遍的需求.
\r\n
\r\n    Mustang实现了JSR 199,   提供了Java编译器API(应用程序接口),允许你从一个Java应用程序中去编译其他的Java源程序--比如在应用程序中动态生成的一些源代码..
\r\n
\r\n Security:安全性
\r\n    Java SE 6的安全部分,增加了 XML-Digital Signature (XML-DSIG) APIs, 整合了GSS/Kerberos的操作API,LDAP上的JAAS认证。

\r\n

\r\n Instrumentation
\r\n    利用 Java 代码,即 java.lang.instrument 做动态 Instrumentation 是 Java SE 5 的新特性,它把 Java 的 instrument 功能从本地代码中解放出来,使之可以用 Java 代码的方式解决问题。在 Java SE 6 里面,instrumentation 包被赋予了更强大的功能:启动后的 instrument、本地代码(native code)instrument,以及动态改变 classpath 等等。在 Java SE 5 当中,开发者只能在 premain 当中施展想象力,所作的 Instrumentation 也仅限与 main 函数执行前,这样的方式存在一定的局限性。在 Java SE 6 的 Instrumentation 当中,有一个跟 premain“并驾齐驱”的“agentmain”方法,可以在 main 函数开始运行之后再运行。
\r\n
\r\n Http增强
\r\n     在 Java SE 6 当中,围绕着 HTTP 协议出现了很多实用的新特性:NTLM 认证提供了一种 Window 平台下较为安全的认证机制;JDK 当中提供了一个轻量级的 HTTP 服务器;提供了较为完善的 HTTP Cookie 管理功能;更为实用的 NetworkInterface;DNS 域名的国际化支持等等。
\r\n     HTTP Cookie管理可以应用客户操作临时变量的保存,如查询条件,当前状态等

\r\n

\r\n     Java 语言从诞生的那天起,就非常注重网络编程方面的应用。随着互联网应用的飞速发展,Java 的基础类库也不断地对网络相关的 API 进行加强和扩展。在 Java SE 6 当中,围绕着 HTTP 协议出现了很多实用的新特性:NTLM 认证提供了一种 Window 平台下较为安全的认证机制;JDK 当中提供了一个轻量级的 HTTP 服务器;提供了较为完善的 HTTP Cookie 管理功能;更为实用的 NetworkInterface;DNS 域名的国际化支持等等。

\r\n

\r\n          NTML认证 不可避免,网络中有很多资源是被安全域保护起来的。访问这些资源需要对用户的身份进行认证。下面是一个简单的例子:
\r\n  

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\nimport java.net.*;\r\nimport java.io.*;\r\n\r\npublic class Test {\r\n public static void main(String[] args) throws Exception {\r\n  URL url = new URL("http://PROTECTED.com");\r\n  URLConnection connection = url.openConnection();\r\n  InputStream in = connection.getInputStream();\r\n  byte[] data = new byte[1024];\r\n  while(in.read(data)>0)\r\n  {\r\n   //do something for data\r\n  }\r\n  in.close();\r\n }\r\n}
\r\n
\r\n      
\r\n        Java 程序试图从一个要求认证的网站读取信息的时候,也就是说,从联系于 http://Protected.com 这个 URLConnection 的 InputStream 中 read 数据时,会引发 FileNotFoundException。尽管笔者认为,这个 Exception 的类型与实际错误发生的原因实在是相去甚远;但这个错误确实是由网络认证失败所导致的。
\r\n

\r\n     要解决这个问题,有两种方法:

\r\n

\r\n     其一,是给 URLConnection 设定一个“Authentication”属性:
\r\n  

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\nString credit = USERNAME + ":" + PASSWORD;\r\nString encoding = new sun.misc.BASE64Encoder().encode (credit.getBytes());\r\nconnection.setRequestProperty ("Authorization", "Basic " + encoding);
\r\n
\r\n
\r\n       这里假设 http://PROTECTED.COM 使用了基本(Basic)认证类型。
\r\n

\r\n    从上面的例子,我们可以看出,设定 Authentication 属性还是比较复杂的:用户必须了解认证方式的细节,才能将用户名/密码以一定的规范给出,然后用特定的编码方式加以编码。Java 类库有没有提供一个封装了认证细节,只需要给出用户名/密码的工具呢?

\r\n

\r\n    这就是我们要介绍的另一种方法,使用 java.net.Authentication 类。

\r\n

\r\n    每当遇到网站需要认证的时候,HttpURLConnection 都会向 Authentication 类询问用户名和密码。

\r\n

\r\n    Authentication 类不会知道究竟用户应该使用哪个 username/password 那么用户如何向 Authentication 类提供自己的用户名和密码呢?

\r\n

\r\n    提供一个继承于 Authentication 的类,实现 getPasswordAuthentication 方法,在 PasswordAuthentication 中给出用户名和密码:

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\nclass DefaultAuthenticator extends Authenticator {\r\n public PasswordAuthentication getPasswordAuthentication () {\r\n  return new PasswordAuthentication ("USER", "PASSWORD".toCharArray());\r\n }\r\n}
\r\n
\r\n
\r\n

\r\n    然后,将它设为默认的(全局)Authentication:
\r\n  

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\nAuthenticator.setDefault (new DefaultAuthenticator());
\r\n
\r\n

\r\n    那么,不同的网站需要不同的用户名/密码又怎么办呢?

\r\n

\r\n    Authentication 提供了关于认证发起者的足够多的信息,让继承类根据这些信息进行判断,在 getPasswordAuthentication 方法中给出了不同的认证信息:

\r\n
    \r\n
  • \r\n getRequestingHost()
  • \r\n
  • \r\n getRequestingPort()
  • \r\n
  • \r\n getRequestingPrompt()
  • \r\n
  • \r\n getRequestingProtocol()
  • \r\n
  • \r\n getRequestingScheme()
  • \r\n
  • \r\n getRequestingURL()
  • \r\n
  • \r\n getRequestingSite()
  • \r\n
  • \r\n getRequestorType()
  • \r\n
\r\n

\r\n    另一件关于 Authentication 的重要问题是认证类型。不同的认证类型需要 Authentication 执行不同的协议。至 Java SE 6.0 为止,Authentication 支持的认证方式有:

\r\n
    \r\n
  • \r\n HTTP Basic authentication
  • \r\n
  • \r\n HTTP Digest authentication
  • \r\n
  • \r\n NTLM
  • \r\n
  • \r\n Http SPNEGO Negotiate\r\n
      \r\n
    • \r\n Kerberos
    • \r\n
    • \r\n NTLM
    • \r\n
    \r\n
  • \r\n
\r\n

\r\n    这里我们着重介绍 NTLM。

\r\n

\r\n    NTLM 是 NT LAN Manager 的缩写。早期的 SMB 协议在网络上明文传输口令,这是很不安全的。微软随后提出了 WindowsNT 挑战/响应验证机制,即 NTLM。

\r\n

\r\n    NTLM 协议是这样的:

\r\n
    \r\n
  1. \r\n 客户端首先将用户的密码加密成为密码散列;
  2. \r\n
  3. \r\n 客户端向服务器发送自己的用户名,这个用户名是用明文直接传输的;
  4. \r\n
  5. \r\n 服务器产生一个 16 位的随机数字发送给客户端,作为一个 challenge(挑战) ;
  6. \r\n
  7. \r\n 客户端用步骤1得到的密码散列来加密这个 challenge ,然后把这个返回给服务器;
  8. \r\n
  9. \r\n 服务器把用户名、给客户端的 challenge 、客户端返回的 response 这三个东西,发送域控制器 ;
  10. \r\n
  11. \r\n 域控制器用这个用户名在 SAM 密码管理库中找到这个用户的密码散列,然后使用这个密码散列来加密 challenge;
  12. \r\n
  13. \r\n 域控制器比较两次加密的 challenge ,如果一样,那么认证成功;
  14. \r\n
\r\n

\r\n    Java 6 以前的版本,是不支持 NTLM 认证的。用户若想使用 HttpConnection 连接到一个使用有 Windows 域保护的网站时,是无法通过 NTLM 认证的。另一种方法,是用户自己用 Socket 这样的底层单元实现整个协议过程,这无疑是十分复杂的。

\r\n

\r\n 终于,Java 6 的 Authentication 类提供了对 NTLM 的支持。使用十分方便,就像其他的认证协议一样:

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\nclass DefaultAuthenticator extends Authenticator {\r\n private static String username = "username ";\r\n private static String domain =  "domain ";\r\n private static String password =  "password ";\r\n\r\n public PasswordAuthentication getPasswordAuthentication() {\r\n  String usernamewithdomain = domain + "/ "+username;\r\n  return (new PasswordAuthentication(usernamewithdomain, password.toCharArray()));\r\n }\r\n}
\r\n
\r\n

\r\n 这里,根据 Windows 域账户的命名规范,账户名为域名+”/”+域用户名。如果不想每生成 PasswordAuthentication 时,每次添加域名,可以设定一个系统变量名“http.auth.ntlm.domain“。

\r\n

\r\n Java 6 中 Authentication 的另一个特性是认证协商。目前的服务器一般同时提供几种认证协议,根据客户端的不同能力,协商出一种认证方式。比如,IIS 服务器会同时提供 NTLM with kerberos 和 NTLM 两种认证方式,当客户端不支持 NTLM with kerberos 时,执行 NTLM 认证。

\r\n

\r\n 目前,Authentication 的默认协商次序是:

\r\n

\r\n  

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\nGSS/SPNEGO -> Digest -> NTLM -> Basic
\r\n
\r\n

\r\n 那么 kerberos 的位置究竟在哪里呢?

\r\n

\r\n 事实上,GSS/SPNEGO 以 JAAS 为基石,而后者实际上就是使用 kerberos 的。

\r\n

\r\n 轻量级 HTTP 服务器

\r\n

\r\n Java 6 还提供了一个轻量级的纯 Java Http 服务器的实现。下面是一个简单的例子:

\r\n

\r\n  

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\npublic static void main(String[] args) throws Exception{\r\n HttpServerProvider httpServerProvider = HttpServerProvider.provider();\r\n InetSocketAddress addr = new InetSocketAddress(7778);\r\n HttpServer httpServer = httpServerProvider.createHttpServer(addr, 1);\r\n httpServer.createContext("/myapp/", new MyHttpHandler());\r\n httpServer.setExecutor(null);\r\n httpServer.start();\r\n System.out.println("started");\r\n}\r\n\r\nstatic class MyHttpHandler implements HttpHandler{\r\n public void handle(HttpExchange httpExchange) throws IOException {\r\n  String response = "Hello world!";\r\n  httpExchange.sendResponseHeaders(200, response.length());\r\n  OutputStream out = httpExchange.getResponseBody();\r\n  out.write(response.getBytes());\r\n  out.close();\r\n }\r\n}
\r\n
\r\n

\r\n 然后,在浏览器中访问 http://localhost:7778/myapp/,我们得到:

\r\n

\r\n
\r\n 图一 浏览器显示

\r\n

\r\n Hellword !

\r\n

\r\n  

\r\n

\r\n 首先,HttpServer 是从 HttpProvider 处得到的,这里我们使用了 JDK 6 提供的实现。用户也可以自行实现一个 HttpProvider 和相应的 HttpServer 实现。

\r\n

\r\n 其次,HttpServer 是有上下文(context)的概念的。比如,http://localhost:7778/myapp/ 中“/myapp/”就是相对于 HttpServer Root 的上下文。对于每个上下文,都有一个 HttpHandler 来接收 http 请求并给出回答。

\r\n

\r\n 最后,在 HttpHandler 给出具体回答之前,一般先要返回一个 Http head。这里使用 HttpExchange.sendResponseHeaders(int code, int length)。其中 code 是 Http 响应的返回值,比如那个著名的 404。length 指的是 response 的长度,以字节为单位。

\r\n

\r\n Cookie 管理特性

\r\n

\r\n Cookie 是 Web 应用当中非常常用的一种技术, 用于储存某些特定的用户信息。虽然,我们不能把一些特别敏感的信息存放在 Cookie 里面,但是,Cookie 依然可以帮助我们储存一些琐碎的信息,帮助 Web 用户在访问网页时获得更好的体验,例如个人的搜索参数,颜色偏好以及上次的访问时间等等。网络程序开发者可以利用 Cookie 来创建有状态的网络会话(Stateful Session)。 Cookie 的应用越来越普遍。在 Windows 里面,我们可以在“Documents And Settings”文件夹里面找到IE使用的 Cookie,假设用户名为 admin,那么在 admin 文件夹的 Cookies 文件夹里面,我们可以看到名为“admin@(domain)”的一些文件,其中的 domain 就是表示创建这些 Cookie 文件的网络域, 文件里面就储存着用户的一些信息。

\r\n

\r\n JavaScript 等脚本语言对 Cookie 有着很不错的支持。 .NET 里面也有相关的类来支持开发者对 Cookie 的管理。 不过,在 Java SE 6 之前, Java一直都没有提供 Cookie 管理的功能。在 Java SE 5 里面, java.net 包里面有一个 CookieHandler 抽象类,不过并没有提供其他具体的实现。到了 Java SE 6, Cookie 相关的管理类在 Java 类库里面才得到了实现。有了这些 Cookie 相关支持的类,Java 开发者可以在服务器端编程中很好的操作 Cookie, 更好的支持 HTTP 相关应用,创建有状态的 HTTP 会话。

\r\n
    \r\n
  • \r\n 用 HttpCookie 代表 Cookie\r\n

    \r\n java.net.HttpCookie 类是 Java SE 6 新增的一个表示 HTTP Cookie 的新类, 其对象可以表示 Cookie 的内容, 可以支持所有三种 Cookie 规范:

    \r\n
      \r\n
    • \r\n Netscape 草案
    • \r\n
    • \r\n RFC 2109 - http://www.ietf.org/rfc/rfc2109.txt
    • \r\n
    • \r\n RFC 2965 - http://www.ietf.org/rfc/rfc2965.txt
    • \r\n
    \r\n

    \r\n 这个类储存了 Cookie 的名称,路径,值,协议版本号,是否过期,网络域,最大生命期等等信息。

    \r\n
  • \r\n
  • \r\n 用 CookiePolicy 规定 Cookie 接受策略\r\n

    \r\n java.net.CookiePolicy 接口可以规定 Cookie 的接受策略。 其中唯一的方法用来判断某一特定的 Cookie 是否能被某一特定的地址所接受。 这个类内置了 3 个实现的子类。一个类接受所有的 Cookie,另一个则拒绝所有,还有一个类则接受所有来自原地址的 Cookie。

    \r\n
  • \r\n
  • \r\n 用CookieStore 储存 Cookie\r\n

    \r\n java.net.CookieStore 接口负责储存和取出 Cookie。 当有 HTTP 请求的时候,它便储存那些被接受的 Cookie; 当有 HTTP 回应的时候,它便取出相应的 Cookie。 另外,当一个 Cookie 过期的时候,它还负责自动删去这个 Cookie。

    \r\n
  • \r\n
  • \r\n 用 CookieManger/CookieHandler 管理 Cookie\r\n

    \r\n java.net.CookieManager 是整个 Cookie 管理机制的核心,它是 CookieHandler 的默认实现子类。下图显示了整个 HTTP Cookie 管理机制的结构:

    \r\n
    \r\n
    \r\n 图 2. Cookie 管理类的关系
    \r\n \"图

    \r\n
    \r\n

    \r\n 一个 CookieManager 里面有一个 CookieStore 和一个 CookiePolicy,分别负责储存 Cookie 和规定策略。用户可以指定两者,也可以使用系统默认的 CookieManger。

    \r\n
  • \r\n
  • \r\n 例子\r\n

    \r\n 下面这个简单的例子说明了 Cookie 相关的管理功能:

    \r\n \r\n \r\n \r\n \r\n \r\n \r\n
    \r\n
    \r\n// 创建一个默认的 CookieManager\r\nCookieManager manager = new CookieManager();\r\n\r\n// 将规则改掉,接受所有的 Cookie\r\nmanager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);\r\n\r\n// 保存这个定制的 CookieManager\r\nCookieHandler.setDefault(manager);\r\n\r\n// 接受 HTTP 请求的时候,得到和保存新的 Cookie\r\nHttpCookie cookie = new HttpCookie("...(name)...","...(value)...");\r\nmanager.getCookieStore().add(uri, cookie);\r\n\r\n// 使用 Cookie 的时候:\r\n// 取出 CookieStore\r\nCookieStore store = manager.getCookieStore();\r\n\r\n// 得到所有的 URI\r\nList<URI> uris = store.getURIs();\r\nfor (URI uri : uris) {\r\n // 筛选需要的 URI\r\n // 得到属于这个 URI 的所有 Cookie\r\n List<HttpCookie> cookies = store.get(uri);\r\n for (HttpCookie cookie : cookies) {\r\n  // 取出了 Cookie\r\n }\r\n}\r\n\r\n// 或者,取出这个 CookieStore 里面的全部 Cookie\r\n// 过期的 Cookie 将会被自动删除\r\nList<HttpCookie> cookies = store.getCookies();\r\nfor (HttpCookie cookie : cookies) {\r\n // 取出了 Cookie\r\n}
    \r\n
    \r\n
  • \r\n
\r\n

\r\n 其他新特性

\r\n

\r\n NetworkInterface 的增强

\r\n

\r\n 从 Java SE 1.4 开始,JDK 当中出现了一个网络工具类 java.net.NetworkInterface,提供了一些网络的实用功能。 在 Java SE 6 当中,这个工具类得到了很大的加强,新增了很多实用的方法。例如:

\r\n
    \r\n
  • \r\n public boolean isUp()\r\n

    \r\n 用来判断网络接口是否启动并运行

    \r\n
  • \r\n
  • \r\n public boolean isLoopback()\r\n

    \r\n 用来判断网络接口是否是环回接口(loopback)

    \r\n
  • \r\n
  • \r\n public boolean isPointToPoint()\r\n

    \r\n 用来判断网络接口是否是点对点(P2P)网络

    \r\n
  • \r\n
  • \r\n public boolean supportsMulticast()\r\n

    \r\n 用来判断网络接口是否支持多播

    \r\n
  • \r\n
  • \r\n public byte[] getHardwareAddress()\r\n

    \r\n 用来得到硬件地址(MAC)

    \r\n
  • \r\n
  • \r\n public int getMTU()\r\n

    \r\n 用来得到最大传输单位(MTU,Maximum Transmission Unit)

    \r\n
  • \r\n
  • \r\n public boolean isVirtual()\r\n

    \r\n 用来判断网络接口是否是虚拟接口

    \r\n
  • \r\n
\r\n

\r\n 关于此工具类的具体信息,请参考 Java SE 6 相应文档(见 参考资源)。

\r\n

\r\n 域名的国际化

\r\n

\r\n 在最近的一些 RFC 文档当中,规定 DNS 服务器可以解析除开 ASCII 以外的编码字符。有一个算法可以在这种情况下做 Unicode 与 ASCII 码之间的转换,实现域名的国际化。java.net.IDN 就是实现这个国际化域名转换的新类,IDN 是“国际化域名”的缩写(internationalized domain names)。这个类很简单,主要包括 4 个静态函数,做字符的转换。

\r\n

\r\n <!--JDK1.6 的新特性 (HTTP 增强) end-->

\r\n

\r\n
\r\n JMX与系统管理

\r\n

\r\n 管理系统的构架
\r\n 图 1. 管理系统构架

\r\n

\r\n  

\r\n
\r\n \"\"
\r\n

\r\n 上图分析了管理系统的基本构架模式。其中 Agent / SubAgent 起到的就是翻译的作用:把 IT 资源报告的消息以管理系统能理解的方式传送出去。

\r\n

\r\n 也许读者有会问,为什么需要 Agent 和 SubAgent 两层体系呢?这里有两个现实的原因:
\r\n
\r\n 管理系统一般是一个中央控制的控制软件,而 SubAgent 直接监控一些资源,往往和这些资源分布在同一物理位置。当这些 SubAgent 把状态信息传输到管理系统或者传达管理系统的控制指令的时候,需要提供一些网络传输的功能。

\r\n
    \r\n
  1. \r\n 管理系统的消息是有一定规范的,消息的翻译本身是件复杂而枯燥的事情。
  2. \r\n
\r\n

\r\n 一般来说,管理系统会将同一物理分布或者功能类似的 SubAgent 分组成一组,由一个共用的 Agent 加以管理。在这个 Agent 里封装了 1 和 2 的功能。

\r\n

\r\n JMX 和管理系统

\r\n

\r\n JMX 既是 Java 管理系统的一个标准,一个规范,也是一个接口,一个框架。图 2 展示了 JMX 的基本架构。
\r\n 图 2. JMX 构架\"\"和其它的资源系统一样,JMX 是管理系统和资源之间的一个接口,它定义了管理系统和资源之间交互的标准。javax.management.MBeanServer 实现了 Agent 的功能,以标准的方式给出了管理系统访问 JMX 框架的接口。而 javax.management.MBeans 实现了 SubAgent 的功能,以标准的方式给出了 JMX 框架访问资源的接口。而从类库的层次上看,JMX 包括了核心类库 java.lang.management 和 javax.management 包。java.lang.management 包提供了基本的 VM 监控功能,而 javax.management 包则向用户提供了扩展功能。 JMX帮助开发者监控JVM的信息。
\r\n
\r\n 编辑器API
\r\n      JDK 6 提供了在运行时调用编译器的 API。在传统的 JSP 技术中,服务器处理 JSP 通常需要进行下面 6 个步骤:

\r\n
    \r\n
  1. \r\n 分析 JSP 代码;
  2. \r\n
  3. \r\n 生成 Java 代码;
  4. \r\n
  5. \r\n 将 Java 代码写入存储器;
  6. \r\n
  7. \r\n 启动另外一个进程并运行编译器编译 Java 代码;
  8. \r\n
  9. \r\n 将类文件写入存储器;
  10. \r\n
  11. \r\n 服务器读入类文件并运行;
  12. \r\n
\r\n

\r\n      但如果采用运行时编译,可以同时简化步骤 4 和 5,节约新进程的开销和写入存储器的输出开销,提高系统效率。实际上,在 JDK 5 中,Sun 也提供了调用编译器的编程接口。然而不同的是,老版本的编程接口并不是标准 API 的一部分,而是作为 Sun 的专有实现提供的,而新版则带来了标准化的优点。
\r\n      新 API 的第二个新特性是可以编译抽象文件,理论上是任何形式的对象 —— 只要该对象实现了特定的接口。有了这个特性,上述例子中的步骤 3 也可以省略。整个 JSP 的编译运行在一个进程中完成,同时消除额外的输入输出操作。
\r\n      第三个新特性是可以收集编译时的诊断信息。作为对前两个新特性的补充,它可以使开发人员轻松的输出必要的编译错误或者是警告信息,从而省去了很多重定向的麻烦

\r\n

\r\n 一些有趣的新特性:
\r\n
\r\n 1 本地行为 java.awt.Desktop
\r\n 比如用默认程序打开文件,用默认浏览器打开url,再也不用那个browserlauncher那么费劲
\r\n 了
\r\n Desktop desk=Desktop.getDesktop();
\r\n desk.browse(new URI("http://www.google.com"));
\r\n desk.open(file)
\r\n desk.print(file)
\r\n
\r\n 2 console下密码输入 java.io.Console
\r\n 再也不用自己写线程去删echo字符了
\r\n Console console = System.console();
\r\n char password[] = console.readPassword("Enter password: ");
\r\n
\r\n 3 获取磁盘空间大小 java.io.File的新方法
\r\n File roots[] = File.listRoots();
\r\n for (File root : roots) {
\r\n System.out.println(root.getPath()+":"+root.getUsableSpace()
\r\n +"/"+root.getTotalSpace());
\r\n }
\r\n
\r\n 4 专利过期,可以提供合法的lzw的gif encoder了
\r\n ImageIO.write(input, "GIF", outputFile);
\r\n
\r\n 5 JAXB2.0 增加了java-to-xml schema,完成java bean,xml间转换非常容易
\r\n
\r\n 6 xml数字签名 javax.xml.crypto,记得以前似乎只有ibm有个类库实现了
\r\n
\r\n 7 编译器,以前是com.sun.tools.javac,现在是javax.tools.JavaCompiler
\r\n 有人写了完全在内存里的生成源文件,编译,反射运行的过程,比较好玩。
\r\n
\r\n 8 脚本引擎,javax.script,内嵌的是Mozilla Rhino1.6r2 支持ECMAScript1.6

\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2844, 'jdk1-5%e6%96%b0%e7%89%b9%e6%80%a7', 'JDK1.5新特性', '2012-10-30 23:23:34', '2019-03-25 21:29:22', '

\r\n    1.泛型(Generics)--为集合(collections)提供编译时类型安全,无需每次从Collections取得一个对象时就进行强制转换(cast)。
\r\n
\r\n    2.增强的“for”循环(Enhanced For loop)--减少迭代器(iterator)的潜在错误(error-proneness)。
\r\n
\r\n    3.自动置入/自动取出(Autoboxing/unboxing)--无需在基本类型(primitive types)(例如double)和包装类型(wrapper types)(例如Double)之间人工地进行转换。
\r\n
\r\n    4.类型安全的枚举(Typesafeenums)--提供类型安全枚举模式的各项好处。
\r\n
\r\n    5.静态导入(Static import)--无需在使用其他类的静态成员变量前缀其类名.这将使得代码更为简洁。
\r\n
\r\n    6.元数据(Metadata)--使编程人员避免编写样板化代码(boiler plate code),并提供机会进行宣告式程式设计(declarative programming)。

\r\n
\r\n   让我们详细讨论每个新特性,并看一些例子。
\r\n
\r\n 1、泛型(Generics)
\r\n
\r\n    泛型是JDK1.5中一个最“酷”的特征。通过引入泛型,我们将获得编译时类型的安全和运行时更小地抛出ClassCastExceptions的可能。在JDK1.5中,你可以声明一个集合将接收/返回的对象的类型。在JDK1.4中,创建雇员名字的清单(List)需要一个集合对象,像下面的语句:
\r\n
\r\n   List listOfEmployeeName = new ArrayList();
\r\n
\r\n   在JDK1.5中,你将使用下面语句
\r\n
\r\n   List<String> listOfEmployeeName = new ArrayList<String>();
\r\n
\r\n   最“酷”的是,如果你试图插入非string类型的值,你将在编译时发现并且修正这类问题。没有泛型,你会发现这样一个bug,当你的客户调用后会告诉你,你所编写的程序抛出ClassCastException异常而崩溃。
\r\n
\r\n   另外,当你从集合中得到一个元素时你无需进行强制转换。故原先为:
\r\n
\r\n   String employeeName = ((String) listOfEmployee.get(i));
\r\n
\r\n   而下面的语句将比上面的更加简单:
\r\n
\r\n   String employeeName = listOfEmployee.get(i);
\r\n
\r\n    不清楚对象的类型而强制转换对象是不合理的,并且更重要的是,它将在运行时失败。假使用户无意间传入一个包含string buffers类型而非string类型的集合,那结果会怎样呢。在Listing A中,客户被要求传入一个编译器无法强制的strings类型集合。Listing B中显示了同样的方法使用泛型是如何实现的。
\r\n
\r\n   Listing A
\r\n   

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\nstaticbooleancheckName(Collection employeeNameList, String name) {\r\n\r\n  for (Iterator i = employeeNamList.iterator(); i.hasNext(); ) {\r\n\r\n  String s = (String) i.next();\r\n\r\n  if(s.equals(name)){\r\n\r\n  return true;\r\n\r\n  //print employee name here ......\r\n\r\n  }\r\n\r\n  }\r\n\r\n  return false;\r\n\r\n  
\r\n
\r\n

\r\n
\r\n
\r\n   Listing B
\r\n  

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n  staticbooleancheckName(Collection<String> employeeNameList, String name) {\r\n\r\n  for (Iterator i = employeeNamList.iterator(); i.hasNext(); ) {\r\n\r\n  if(i.next().equals(name)){\r\n\r\n  return true;\r\n\r\n  //print employee name here ......\r\n\r\n  }\r\n\r\n  }\r\n\r\n  return false;\r\n\r\n  }
\r\n
\r\n

\r\n
\r\n
\r\n   现在,通过方法签名可以清楚知道输入集合必须只能包含strings。如果客户试图传入一个包含string buffers的集合,程序将不会编译。同时注意,该方法不包含任何强制转换。它只需要短短一行,一旦你习惯泛型后,它也更加清晰。
\r\n
\r\n 2、在JDK当前版本下的For循环语法如下:
\r\n
\r\n   

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\nvoid printAll(Collection c) {\r\n\r\n  for (Iterator i = c.iterator(); i.hasNext(); ) {\r\n\r\n  Employee emp = (Employee)i.next();\r\n\r\n  System.out.println(emp.getName());\r\n\r\n  }\r\n\r\n  }
\r\n
\r\n

\r\n
\r\n
\r\n   现在,用增强的For语句实现相同方法:
\r\n  

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\nvoidprintAll(Collection c) {\r\n\r\n  for (Object o : c)\r\n\r\n  System.out.println((TimerTask)o).getName());\r\n\r\n  
\r\n
\r\n

\r\n
\r\n
\r\n   在这类For循环中,你应该将":"看成"in",所以,在该例中可以看成"for Object o in c"。你可以发现这种For循环更具可读性。
\r\n
\r\n 3、自动置入/自动取出(Autoboxing/unboxing)
\r\n
\r\n   Java有基本数据类型,在这些基本数据类型周围又有包装类。通常,编程人员需要将一种类型转换成另一种。看看Listing C.中的代码片断。
\r\n
\r\n   Listing C

\r\n  

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n public class Employee {\r\n\r\n  private static final Integer CHILD = new Integer(0);\r\n\r\n  public static void main(String args[]) {\r\n\r\n  //code for adding n to an Integer\r\n\r\n  int n=10;\r\n\r\n  Integer age= new Integer(30);\r\n\r\n  Integer ageAfterTenYear= new Integer(age.intValue +10);\r\n\r\n  }\r\n\r\n  }\r\n
\r\n
\r\n

\r\n
\r\n   请注意,用于计算ageAfterTenYear的内循环代码看上去是多么杂乱。现在,在Listing D.中看看相同的程序使用autoboxing重写后的样子。
\r\n
\r\n   Listing D

\r\n  

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\npublic class Employee {\r\n\r\n  public static void main(String args[]) {\r\n\r\n  int n=10;\r\n\r\n  Integer age= new Integer(30);\r\n\r\n  Integer ageAfterTenYear= age +10;\r\n\r\n  }\r\n\r\n  
\r\n
\r\n

\r\n
\r\n
\r\n   有一件事值得注意的:在先前,如果你取出(unbox)Null值,它将变为0。在次代码中,编译器将自动地转换Integer为int然后加上10,接着将其转换回Integer.。
\r\n
\r\n 4、类型安全的枚举(Typesafeenums)
\r\n
\r\n   类型安全枚举提供下列特性:
\r\n
\r\n   他们提供编译时类型安全。
\r\n
\r\n   他们都是对象,因此你不需要将他们放入集合中。
\r\n
\r\n   他们作为一种类的实现,因此你可以添加一些方法。
\r\n
\r\n   他们为枚举类型提供了合适的命名空间。
\r\n
\r\n   他们打印的值具有情报性(informative)― 如果你打印一个整数枚举(intenum),你只是看见一个数字,它可能并不具有情报性。
\r\n
\r\n   例一:
\r\n
\r\n   enum Season { winter, spring, summer, fall }
\r\n
\r\n   例二:
\r\n
\r\n   public enum Coin {
\r\n
\r\n   penny(1), nickel(5), dime(10), quarter(25);
\r\n
\r\n   Coin(int value) { this.value = value; }
\r\n
\r\n   private final int value;
\r\n
\r\n   public int value() { return value; }
\r\n
\r\n   }

\r\n
\r\n 5、静态导入(Static import)
\r\n
\r\n   静态导入使代码更易读。通常,你要使用定义在另一个类中的常量(constants),像这样:
\r\n
\r\n  

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n importorg.yyy.pkg.Increment;\r\n\r\n  class Employee {\r\n\r\n  public Double calculateSalary(Double salary{\r\n\r\n  return salary + Increment.INCREMENT * salary;\r\n\r\n  }\r\n\r\n  }
\r\n
\r\n

\r\n
\r\n
\r\n   当使用静态导入,我们无需为常量名前缀类名就能使用这些常量,像这样:
\r\n  

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\nimport static org.yyy.pkg.Increment;\r\n\r\n  class Employee {\r\n\r\n  public Double calculateSalary(Double salary{\r\n\r\n  return salary + INCREMENT * salary;\r\n\r\n  }\r\n\r\n  }
\r\n
\r\n

\r\n
\r\n   注意,我们可以调用INCREMENT这一常量而不要使用类名Increment.。
\r\n
\r\n 6、元数据(Metadata)
\r\n
\r\n   元数据特征志于使开发者们借助厂商提供的工具可以进行更简易的开发。看一看Listing E.中的代码。
\r\n
\r\n   Listing E

\r\n  

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n importorg.yyy.hr;\r\n\r\n  public interface EmployeeI extends Java.rmi.Remote {\r\n\r\n  public String getName()\r\n\r\n  throwsJava.rmi.RemoteException;\r\n\r\n  public String getLocation ()\r\n\r\n  throwsJava.rmi.RemoteException;\r\n\r\n  }\r\n\r\n  public class EmployeeImpl implements EmployeeI {\r\n\r\n  public String getName(){\r\n\r\n  }\r\n\r\n  public String getLocation (){\r\n\r\n  }\r\n\r\n  }
\r\n
\r\n

\r\n
\r\n
\r\n   通过元数据的支持,你可以改写Listing E中的代码为:
\r\n  

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n importorg.yyy.hr;\r\n\r\n  public class Employee {\r\n\r\n  @Remote public String getName() {\r\n\r\n  ...\r\n\r\n  }\r\n\r\n  @Remote public public String getLocation() {\r\n\r\n  ...\r\n\r\n  }\r\n\r\n  }\r\n
\r\n
\r\n

\r\n
\r\n
\r\n JDK1.5新特性之Java Generics
\r\n
\r\n    在JDK1.5之前的版本中,对于一个Collection类库中的容器类实例,可将任意类型
\r\n
\r\n    对象加入其中(都被当作Object实例看待);从容器中取出的对象也只是一个Object实例,需要将其强制转型为期待的类型,这种强制转型的运行时正确性由程序员自行保证。
\r\n
\r\n 例如以下代码片断:
\r\n
\r\n List intList = new ArrayList(); //创建一个List,准备存放一些Integer实例
\r\n intList.add(new Integer(0));
\r\n intList.add(“1”); //不小心加入了一个字符串;但在编译和运行时都不报错,只有仔细的代码走
\r\n                        //才能揪出
\r\n Integer i0 = (Integer)intList.get(0);
\r\n Integer i1 = (Integer)intList.get(1); //编译通过,直到运行时才抛ClassCastException 

\r\n
\r\n 而在JDK1.5中,可以创建一个明确只能存放某种特定类型对象的容器类实例,例如如下代码:
\r\n List<Integer> intList = new ArrayList<Integer>(); //intList为存放Integer实例的List
\r\n intList.add(new Integer(0));
\r\n Integer i0 = intList.get(0); //无需(Integer)强制转型;List<Integer>的get()返回的就是Integer类型对象
\r\n intList.add(“1”); //编译不通过,因为List<Integer>的add()方法只接受Integer类型的参数 

\r\n
\r\n    “List<Integer> intList = new ArrayList<Integer>();”就是最简单且最常用的Generic应用;显然,运用Generic后的代码更具可读性和健壮性。
\r\n
\r\n 2 Generic类
\r\n    JDK1.5中Collection类库的大部分类都被改进为Generic类。以下是从JDK1.5源码中
\r\n
\r\n    截取的关于List和Iterator接口定义的代码片断:

\r\n  

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\npublic interface List<E> {\r\n       void add(E x);\r\n       Iterator<E> iterator;\r\n}\r\n\r\npublic interface Iterator<E> {\r\n       E next();\r\n       boolean hasNext();\r\n}
\r\n
\r\n

\r\n
\r\n 以List为例,“public interface List<E>”中的E是List的类型参数,用户在使用List时可为类型参数指定一个确定类型值(如List<Integer>)。类型值为Java编译器所用,确保用户代码类型安全。例如,编译器知道 List<Integer>的add()方法只接受Integer类型的参数,因此如果你在代码中将一个字符串传入add()将导致编译错 误;编译器知道Iterator<Integer>的next()方法返回一个Integer的实例,你在代码中也就无需对返回结果进行 (Integer)强制转型。代码检验通过(语法正确且不会导致运行时类型安全问题)后,编译器对现有代码有一个转换工作。简单的说,就是去除代码中的类 型值信息,在必要处添加转型代码。例如如下代码:
\r\n
\r\n  

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\npublic String demo() {\r\n\r\n       List<String> strList = new ArrayList<String>();\r\n\r\n       strList.add(“Hello!”);\r\n\r\n       return strList.get(0);\r\n\r\n}
\r\n
\r\n

\r\n
\r\n 编译器在检验通过后,将其转换为:
\r\n  

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\npublic String demo() {\r\n\r\n       List strList = new ArrayList(); //去除类型值<String>\r\n\r\n       strList.add(“Hello!”);\r\n\r\n       return (String)strList.get(0);  //添加转型动作代码(String)\r\n\r\n} 
\r\n
\r\n

\r\n
\r\n    可见,类型值信息只为Java编译器在编译时所用,确保代码无类型安全问题;验证通过之后,即被去除。对于JVM而言,只有如JDK1.5之前版本一样的 List,并无List<Integer>和List<String>之分。这也就是Java Generics实现中关键技术Erasure的基本思想。以下代码在控制台输出的就是“true”。
\r\n
\r\n List<String> strList = new ArrayList<String>();
\r\n
\r\n List<Integer> intList = new ArrayList<Integer>();
\r\n
\r\n System.out.println(strList.getClass() == intList.getClass()); 

\r\n
\r\n     可以将Generic理解为:为提高Java代码类型安全性(在编译时确保,而非等到运行时才暴露),Java代码与Java编译器之间新增的一种约定规 范。Java编译器在编译结果*.class文件中供JVM读取的部分里没有保留Generic的任何信息;JVM看不到Generic的存在。
\r\n
\r\n     对于Generic类(设为GenericClass)的类型参数(设为T):
\r\n
\r\n 1)由于对于JVM而言,只有一个GenericClass类,所以GenericClass类的静态字段和静态方法的定义中不能使用T。T只能出现在 GenericClass的非静态字段或非静态方法中。也即T是与GenericClass的实例相关的信息;
\r\n
\r\n 2)T只在编译时被编译器理解,因此也就不能与运行时被JVM理解并执行其代表的操作的操作符(如instanceof 和new)联用。

\r\n  

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\nclass GenericClass<T> {\r\n\r\n    T t1;\r\n\r\n    public void method1(T t){\r\n\r\n       t1 = new T(); //编译错误,T不能与new联用\r\n\r\n       if (t1 instanceof T) {}; //编译错误,T不能与instanceof联用\r\n\r\n    };\r\n\r\n    static T t2; //编译错误,静态字段不能使用T\r\n\r\n    public static void method2(T t){};//编译错误,静态方法不能使用T\r\n\r\n}\r\n\r\n       Generic类可以有多个类型参数,且类型参数命名一般为大写单字符。例如Collection类库中的Map声明为:\r\n\r\npublic interface Map<K,V> {\r\n\r\n       ……;\r\n\r\n}\r\n
\r\n
\r\n

\r\n
\r\n 3 Generic类和原(Raw)类
\r\n    对每一个Generic类,用户在使用时可以不指定类型参数。例如,对于List<E>,用户
\r\n
\r\n    可以以“List<String> list;”方式使用,也可以以“List list;”方式使用。“List<String>”被称为参数化的Generic类(类型参数被赋值),而“List”称为原类。原类 List的使用方式和效果与JDK1.5之前版本List的一样;使用原类也就失去了Generic带来的可读性和健壮性的增强。
\r\n
\r\n     允许原类使用方式的存在显然是为了代码的向前兼容:即JDK1.5之前的代码在JDK1.5下仍然编译通过且正常运行。
\r\n
\r\n     当你在JDK1.5中使用原类并向原类实例中添加对象时,编译器会产生警告,因为它无法保证待添加对象类型的正确性。编译通过是为了保证代码向前兼容,产生警告是提醒潜在的风险。
\r\n
\r\n public void test () {
\r\n
\r\n     List list = new ArrayList();
\r\n
\r\n     list.add("tt");//JDK1.5编译器对此行产生警告
\r\n
\r\n }

\r\n
\r\n 4 Generic类和子类
\r\n List<String> ls = new ArrayList<String>();
\r\n
\r\n List<Object> lo = ls; //编译错误:Type mismatch: cannot convert from List<Dummy> to List<Object>

\r\n
\r\n    以上第二行代码导致的编译错误“Type mismatch: cannot convert from List<Dummy> to List<Object>” 是不是有点出人意料?直观上看,就像String是Object的子类,因此‘Object o = “String”’合法一样,存放String的List是存放Object的List的子类,因此第二行应该是合法的。反过来分析,如果第二行是合法的,那么如下会导致运行时异常的代码也是合法的:
\r\n
\r\n lo.add(new Object); //会导致在ls中添加了非String对象
\r\n
\r\n String s = ls.get(0); //ls.get(0)返回的实际上只是一个Object实例,会导致ClassCastException 

\r\n
\r\n     编译器显然不允许此种情形发生,因此不允许“List<Object> lo = ls”编译通过。
\r\n
\r\n     因此,直观上的“存放String的List是存放Object的List的子类”是错误的。更一般的说,设Foo是Bar的子类,G是Generic类型声明,G<Foo>不是G<Bar>的子类。
\r\n
\r\n 5 参数化的Generic类和数组
\r\n    我们知道,如果T是S的子类,则T[]也是S[]的子类。因此,如下代码编译通过,只在运行时于第三行代码处抛ArrayStoreException。
\r\n
\r\n String[] words = new String[10];
\r\n
\r\n Object[] objects = words;
\r\n
\r\n Objects[0] = new Object(); //编译通过,但运行时会抛ArrayStoreException

\r\n
\r\n
\r\n 再分析如下代码:
\r\n
\r\n List<String>[] wordLists = new ArrayList<String>[10];
\r\n
\r\n ArrayList<Integer> integerList = new ArrayList<Integer>();
\r\n
\r\n integerList.add(123);
\r\n
\r\n Object[] objects = wordLists;
\r\n
\r\n objects[0] = integerList;//运行时不出错,因为运行时ArrayList<String>和ArrayList<Integer>都为ArrayList
\r\n
\r\n String s = wordlists[0].get(0); //编译通过,运行时抛ClassCastException 

\r\n
\r\n    就出现了“正确使用了Generic,但在运行时仍然出现ClassCastException”的情形。显然Java编译器不允许此种情形的发生。事实上,以上代码的第一行“List<String>[] wordLists = new ArrayList<String>[10];”就是编译不通过的,也就不存在接下来的代码。更一般地说,不能创建参数化的Generic类的数组。
\r\n
\r\n 6 类型参数通配符?
\r\n    由“Generic类和子类”节知,Collection<Object>不是存放其它类型对象的Collection(例如 Collection<String>)的基类(抽象),那么如何表示任一种参数化的Collection的呢?使用 Collection<?>。?即代表任一类型参数值。例如,我们可以很容易写出下面的通用函数printCollection():
\r\n
\r\n public static void printCollection(Collection<?> c) {
\r\n
\r\n     //如此遍历Collection的简洁方式也是JDK1.5新引入的
\r\n
\r\n        for (Object o : c) {
\r\n
\r\n               System.out.println(o);
\r\n
\r\n     }
\r\n
\r\n } 

\r\n
\r\n     这样,既可以将Collection<String>的实例,也可以将Collection<Integer>的实例作为参数调用printCollection()方法。
\r\n
\r\n     然而,要注意一点,你不能往Collection<?>容器实例中加入任何非null元素,例如如下代码的第三行编译不通过:
\r\n
\r\n public static void testAdd(Collection<?> c) {
\r\n
\r\n        c.add(null); //编译通过
\r\n
\r\n        c.add(“test”); //编译错误
\r\n
\r\n } 

\r\n
\r\n     很好理解:c中要存放的对象的具体类型不确定,编译器无法验证待添加对象类型的正确性,因此不能加入对象实例;而null可以看作是任一个类的实例,因而允许加入。
\r\n
\r\n     另外,尽管c中要存放的对象的类型不确定,但我们知道任何类都是Object子类,因此从c中取出的对象都统一作为Object实例。
\r\n
\r\n     更进一步,如果BaseClass代表某个可被继承的类的类名,那么Collection<? extends BaseClass>代表类型参数值为BaseClass或BaseClass某个子类的任一参数化Collection。对于 Collection<? extends BaseClass>的实例c,因为c中要存放的对象具体类型不确定,不能往其加入非null对象,但从c中取出的对象都统一作为 BaseClass实例。事实上,你可以把Collection<?>看作Collection<? extends Object>的简洁形式。
\r\n
\r\n     另一种情形:如果SubClass代表任一个类的类名,那么Collection<? super SubClass>代表类型参数值为SubClass或SubClass某个祖先类的任一参数化Collection。对于 Collection<? super SubClass>的实例c,你可以将SubClass实例加入其中,但从中取出的对象都是Object实例。
\r\n
\r\n 7 Generic方法
\r\n 我们可以定义Generic类,同样可以定义Generic方法,即将方法的一个或多个参数的类型参数化,如代码:
\r\n
\r\n public static <T> void fromArrayToCollection(T[] a, Collection<T> c) {
\r\n
\r\n        for (T o : a) {
\r\n
\r\n            c.add(o); //合法。注意与Collection<?>的区别
\r\n
\r\n     }
\r\n
\r\n } 

\r\n
\r\n
\r\n 我们可以以如下方式调用fromArrayToCollection():

\r\n  

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\nObject[] oa = new Object[100];\r\n\r\nCollection<Object> co = new ArrayList<Object>();\r\n\r\nfromArrayToCollection(oa, co); //此时,T即为Object\r\n\r\n\r\nString[] sa = new String[100];\r\n\r\nCollection<String> cs = new ArrayList<String>();\r\n\r\nfromArrayToCollection(sa, cs); //此时,T即为String\r\n\r\nfromArrayToCollection(sa, co); //此时,T即为Object\r\n\r\nInteger[] ia = new Integer[100];\r\n\r\nFloat[] fa = new Float[100];\r\n\r\nNumber[] na = new Number[100];\r\n\r\nCollection<Number> cn = new ArrayList<Number>();\r\n\r\nfromArrayToCollection(ia, cn); //此时,T即为Number\r\n\r\nfromArrayToCollection(fa, cn); //此时,T即为Number\r\n\r\nfromArrayToCollection(na, cn); //此时,T即为Number\r\n\r\nfromArrayToCollection(na, co); //此时,T即为Object\r\n\r\nfromArrayToCollection(na, cs); //编译错误\r\n
\r\n
\r\n

\r\n
\r\n     通过以上代码可以看出,我们在调用fromArrayToCollection()时,无需明确指定T为何种类型(与Generic类的使用方式不同), 而是像调用一般method一样,直接提供参数值,编译器会根据提供的参数值自动为T赋类型值或提示编译错误(参数值不当)。 

\r\n

\r\n 考虑如下函数sum()
\r\n public static long sum(Collection<? extends Number> numbers) { 
\r\n     long sum = 0; 
\r\n     for (Number n : numbers) { 
\r\n        sum += n.longValue(); 
\r\n     } 
\r\n     return sum;
\r\n } 

\r\n
\r\n 我们也可以将其以Generic方法实现:
\r\n
\r\n public static <T extends Number> long sum(Collection<T> numbers) {
\r\n
\r\n     long sum = 0;
\r\n
\r\n     for (Number n : numbers) {
\r\n
\r\n        sum += n.longValue();
\r\n
\r\n     }
\r\n
\r\n     return sum;
\r\n } 

\r\n
\r\n     那么对于一个方法,当要求参数类型可变时,是采用Generic方法,还是采用类型参数通配符方式呢?一般而言,如果参数类型间或参数类型与返回值类型间存在某种依赖关系,则采取Generic方法,否则采取类型参数通配符方式。
\r\n
\r\n     这一原则在Collection类库的源代码中得到了很好的体现,例如Collection接口的containsAll()、addAll()和toArray()方法:
\r\n
\r\n interface Collection<E> {
\r\n
\r\n        public boolean containsAll(Collecion<?> c); //参数间类型以及参数与返回,值间类型无依赖 
\r\n
\r\n        <T> T[] toArray(T[] a); //参数a与返回值都是相同类的数组,有依赖
\r\n } 

\r\n
\r\n 当然,根据需要,二者也可以结合使用,例如Collections中的copy()方法: 

\r\n

\r\n
\r\n class Collections {
\r\n
\r\n        public static <T> void copy(List<T> dest, List<? extends T> src) {
\r\n
\r\n            …….
\r\n
\r\n        }
\r\n
\r\n }

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2845, 'uml-use-case-diagram-explanation', 'UML用例图详解', '2012-10-30 00:41:33', '2019-03-25 21:29:22', '
\r\n

\r\n    用例图主要用来图示化系统的主事件流,它主要用来描述客户的需求,即用户希望系统具备的完成一定功能的动作,通俗地理解用例就是软件的功能模块,所以是设计系统分析阶段的起点,设计人员根据客户的需求来创建和解释用例图,用来描述软件应具备哪些功能模块以及这些模块之间的调用关系,用例图包含了用例和参与者,用例之间用关联,以求把系统的整个结构和功能反映给非技术人员(通常是软件的用户),对应的是软件的结构和功能分解
\r\n
\r\n    用例是从系统外部可见的行为,是系统为某一个或几个参与者(Actor)提供的一段完整的服务。从原则上来讲,用例之间都是独立、并列的,它们之间并不存在着包含从属关系。但是为了体现一些用例之间的业务关系,提高可维护性和一致性,用例之间可以抽象出包含(include)扩展(extend)泛化(generalization)几种关系。
\r\n
\r\n    共性:都是从现有的用例中抽取出公共的那部分信息,作为一个单独的用例,然后通后过不同的方法来重用这个公共的用例,以减少模型维护的工作量。

\r\n

\r\n
\r\n 1、包含(include)

\r\n

\r\n    包含关系:使用包含(Inclusion)用例来封装一组跨越多个用例的相似动作(行为片断),以便多个基(Base)用例复用。基用例控制与包含用例的关系,以及被包含用例的事件流是否会插入到基用例的事件流中。基用例可以依赖包含用例执行的结果,但是双方都不能访问对方的属性。
\r\n
\r\n    包含关系对典型的应用就是复用,也就是定义中说的情景。但是有时当某用例的事件流过于复杂时,为了简化用例的描述,我们也可以把某一段事件流抽象成为一个被包含的用例;相反,用例划分太细时,也可以抽象出一个基用例,来包含这些细颗粒的用例。这种情况类似于在过程设计语言中,将程序的某一段算法封装成一个子过程,然后再从主程序中调用这一子过程。 

\r\n

\r\n    例如:业务中,总是存在着维护某某信息的功能,如果将它作为一个用例,那新建、编辑以及修改都要在用例详述中描述,过于复杂;如果分成新建用例、编辑用例和删除用例,则划分太细。这时包含关系可以用来理清关系。
\r\n
\r\n \"\"

\r\n

\r\n 2、扩展(extend)

\r\n

\r\n    扩展关系:将基用例中一段相对独立并且可选的动作,用扩展(Extension)用例加以封装,再让它从基用例中声明的扩展点(Extension Point)上进行扩展,从而使基用例行为更简练和目标更集中。扩展用例为基用例添加新的行为扩展用例可以访问基用例的属性,因此它能根据基用例中扩展点的当前状态来判断是否执行自己。但是扩展用例对基用例不可见。

\r\n

\r\n    对于一个扩展用例,可以在基用例上有几个扩展点。   
\r\n
\r\n    例如,系统中允许用户对查询的结果进行导出、打印。对于查询而言,能不能导出、打印查询都是一样的,导出、打印是不可见的。导入、打印和查询相对独立,而且为查询添加了新行为。因此可以采用扩展关系来描述:
\r\n
\r\n
\r\n \"\"
\r\n
\r\n
\r\n 4、泛化(generalization)

\r\n

\r\n    泛化关系:子用例和父用例相似,但表现出更特别的行为;子用例将继承父用例的所有结构、行为和关系。子用例可以使用父用例的一段行为,也可以重载它。父用例通常是抽象的。在实际应用中很少使用泛化关系,子用例中的特殊行为都可以作为父用例中的备选流存在。

\r\n

\r\n    例如,业务中可能存在许多需要部门领导审批的事情,但是领导审批的流程是很相似的,这时可以做成泛化关系表示:
\r\n
\r\n
\r\n \"\"
\r\n
\r\n    
\r\n    项目(在线购物系统)案例:
\r\n
\r\n     (1)系统整体用例图
\r\n
\r\n     \"\"
\r\n
\r\n
\r\n    
\r\n     (商品用例图)
\r\n
\r\n    
\r\n    \"\"
\r\n     
\r\n    
\r\n    
\r\n    (购买信息用例)
\r\n   
\r\n    \"\"
\r\n
\r\n    
\r\n     (用户资料用例)
\r\n
\r\n
\r\n    \"\"

\r\n
\r\n    附:UML中扩展和泛化的区别
\r\n
\r\n     泛化表示类似于OO术语“继承”或“多态”。UML中的Use Case泛化过程是将不同Use Case之间的可合并部分抽象成独立的父Use Case,并将不可合并部分单独成各自的子Use Case;包含以及扩展过程与泛化过程类似,但三者对用例关系的优化侧重点是不同的。如下:
\r\n     ●泛化侧重表示子用例间的互斥性;
\r\n     ●包含侧重表示被包含用例对Actor提供服务的间接性;
\r\n     ●扩展侧重表示扩展用例的触发不定性;

\r\n
\r\n     既然用例是系统提供服务的UML表述,那么服务这个过程在所有用例场景中是必然发生的,但发生按照发生条件可分为如下两种情况:
\r\n     ⒈无条件发生:肯定发生的;
\r\n     ⒉有条件发生:未必发生,发生与否取决于系统状态;

\r\n

\r\n     因此,针对用例的三种关系结合系统状态考虑,泛化与包含用例属于无条件发生的用例,而扩展属于有条件发生的用例。进一步,用例的存在是为Actor提供服 务,但用例提供服务的方式可分为间接和直接两种,依据于此,泛化中的子用例提供的是直接服务,而包含中的被包含用例提供的是间接服务。同样,扩展用例提供的也是直接服务,但扩展用例的发生是有条件的。

\r\n

\r\n     另外一点需要提及的是:泛化中的子用例和扩展中的扩展用例均可以作为基本用例事件的备选择流而存在。
\r\n  

\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2846, 'detailed-explanation-of-indexers-in-c', 'C#中索引器详解', '2012-10-29 07:56:32', '2019-03-25 21:29:22', '
\r\n

\r\n 索引器概述

\r\n

\r\n 索引器使得对象可按照与数组相似的方法进行索引。

\r\n

\r\n get 访问器返回值。set 访问器分配值。

\r\n

\r\n this 关键字用于定义索引器。

\r\n

\r\n value 关键字用于定义由 set 索引器分配的值。

\r\n

\r\n 索引器不必根据整数值进行索引,由您决定如何定义特定的查找机制。

\r\n

\r\n 索引器可被重载。

\r\n

\r\n 索引器可以有多个形参,例如当访问二维数组时。

\r\n

\r\n C#语言一个最令人感兴趣的地 方就是类的索引器(indexer)。简单说来,所谓索引器就是一类特殊的属性,通过它们你就可以像引用数组一样引用 自己的类。显然,这一功能在创建集合类的场合特别有用,而在其他某些情况下,比如处理大型文件或者抽象某些有限资源等,能让类具有类似数组的行为当然也是 非常有用的。本文就会引领你设置类来采用索引器。但是,首先让我们概述下属性这个概念以便了解些必要的背景知识。

\r\n

\r\n 属性

\r\n

\r\n   假如你曾经用VB6编写过 程序,那么你应该很熟悉属性方法才对,所谓属性方法其实就是特殊的类成员,它实现了对私有类域的受控访问。在C#语言 中有两种属性方法,其一是get,通过它可以返回私有域的值,其二是set,通过它就可以设置私有域的值。比如说,以下面的代码为例,其间创建了一个 FirstName属性,由它控制对私有类成员firstname的访问:

\r\n

\r\n class Person {
\r\n private string firstname;
\r\n public string FirstName {
\r\n get {return firstname;}
\r\n set {firstname = value;}
\r\n }
\r\n }

\r\n

\r\n 属性声明可以如下编码:
\r\n Person p = new Person();
\r\n p.FirstName = "Lamont";
\r\n Console.WriteLine (p.FirstName); 

\r\n

\r\n   如你你所看到的那样,属性 声明倒更像是域声明,只不过它还声明了两个特殊的成员,按照微软的说法就是所谓的访问函数(accessor)。当某 一表达式的右边调用属性或者属性用作其他子程序(或者函数)的参数时即会调用get访问函数。反之,当表达式左边调用属性并且通过隐式传递value参数 设置私有域值的情况下就会调用set访问函数。你可以创建只读属性,方法是省略set访问函数,这样任何设置属性的尝试都会产生编译错误。

\r\n

\r\n 采用索引器的益处

\r\n

\r\n   说了半天咱们转到正题上来,那么为什么我要兜这个圈子呢?其实,这是因为类的索引器非常像属性,从代码上看也是这样。以下是具有索引器的类示例,通过索引器会返回一个字符串:

\r\n

\r\n class Sample {
\r\n public string this [int index] {
\r\n get {return "You passed " + index; }
\r\n }
\r\n } 

\r\n

\r\n   注意,这里的属性名是 this,意思是回引类的当前实例,参数列表包含在方括号而非括号之内。还有,这是一个只读索引器。为了把它改成读/写类 型,我又添加了一个get访问函数。在定义索引器的时候,你不一定只采用一个参数。索引器参数可以采用任何类型,不过int是通常采用也是最为合理的类 型。同一类中还可能拥有一个以上的索引器(重载)。

\r\n

\r\n   如上定义了Sample类之后,我们就可以把索引器用作某种默认的属性,如下所示:

\r\n

\r\n Sample s = new Sample();
\r\n Console.WriteLine(s[55]); 

\r\n

\r\n 属性和索引器

\r\n

\r\n    属性和索引器之间有好些差别:

\r\n

\r\n   类的每一个属性都必须拥有唯一的名称,而类里定义的每一个索引器都必须拥有唯一的签名(signature)或者参数列表(这样就可以实现索引器重载)。

\r\n

\r\n    属性可以是static(静态的)而索引器则必须是实例成员。

\r\n

\r\n   为索引器定义的访问函数可以访问传递给索引器的参数,而属性访问函数则没有参数。

\r\n

\r\n 接口

\r\n

\r\n   类似数组的行为常受到程序实现者的喜爱,所以你还可以为接口定义索引器,IList和 IDictionary集合接口都声明了索引器以便访问其存储的项目。

\r\n

\r\n   在为接口声明索引器的时候,记住声明只是表示索引器的存在。你只需要提供恰当的访问函数即可,不必包括范围修饰符。以下代码把索引器声明为接口IImplementMe的一部分:

\r\n

\r\n interface IImplementMe {
\r\n string this[int index]
\r\n {
\r\n get;
\r\n set;
\r\n } 

\r\n

\r\n   相应实现的类则必须为IimplementMe的索引器具体定义get和set访问函数。

\r\n

\r\n   以上就是有关索引器的一些基本概述了。现在你应该对索引器在你的开发中所具有的作用有了较深入的了解。

\r\n

\r\n 索引器允许类或结构的实例按照与数组相同的方式进行索引。索引器类似于属性,不同之处在于它们的访问器采用参数。

\r\n

\r\n 在下面的示例中,定义了一个泛型类,并为其提供了简单的 get 和 set 访问器方法(作为分配和检索值的方法)。Program 类为存储字符串创建了此类的一个实例。
\r\n  

\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\nclass SampleCollection<T>\r\n{\r\n    private T[] arr = new T[100];\r\n    public T this[int i]\r\n    {\r\n        get\r\n        {\r\n            return arr[i];\r\n        }\r\n        set\r\n        {\r\n            arr[i] = value;\r\n        }\r\n    }\r\n}\r\n\r\n// This class shows how client code uses the indexer\r\nclass Program\r\n{\r\n    static void Main(string[] args)\r\n    {\r\n        SampleCollection<string> stringCollection = new SampleCollection<string>();\r\n        stringCollection[0] = "Hello, World";\r\n        System.Console.WriteLine(stringCollection[0]);\r\n    }\r\n}\r\n\r\n\r\n
\r\n
\r\n

\r\n
\r\n  

\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2847, 'the-difference-between-vector-and-arraylist-in-java', 'Java中Vector和ArrayList的区别', '2012-10-29 06:24:04', '2019-03-25 21:29:22', '   首先看这两类都实现List接口,而List接口一共有三个实现类,分别是ArrayList、Vector和LinkedList。List用于存放多个元素,能够维护元素的次序,并且允许元素的重复。3个具体实现类的相关区别如下:\r\n
    \r\n
  1. \r\n ArrayList是最常用的List实现类,内部是通过数组实现的,它允许对元素进行快速随机访问。数组的缺点是每个元素之间不能有间隔,当数组大小不满足时需要增加存储能力,就要讲已经有数组的数据复制到新的存储空间中。当从ArrayList的中间位置插入或者删除元素时,需要对数组进行复制、移动、代价比较高。因此,它适合随机查找和遍历,不适合插入和删除。
  2. \r\n
  3. \r\n Vector与ArrayList一样,也是通过数组实现的,不同的是它支持线程的同步,即某一时刻只有一个线程能够写Vector,避免多线程同时写而引起的不一致性,但实现同步需要很高的花费,因此,访问它比访问ArrayList慢。
  4. \r\n
  5. \r\n LinkedList是用链表结构存储数据的,很适合数据的动态插入和删除,随机访问和遍历速度比较慢。另外,他还提供了List接口中没有定义的方法,专门用于操作表头和表尾元素,可以当作堆栈、队列和双向队列使用。
  6. \r\n
\r\n

\r\n      查看Java源代码,发现当数组的大小不够的时候,需要重新建立数组,然后将元素拷贝到新的数组内,ArrayList和Vector的扩展数组的大小不同。
\r\n       ArrayList中:

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\npublic boolean add(E e) {\r\n\r\n     ensureCapacity(size + 1);  // 增加元素,判断是否能够容纳。不能的话就要新建数组\r\n\r\n     elementData[size++] = e;\r\n\r\n     return true;\r\n\r\n }\r\n\r\n  public void ensureCapacity(int minCapacity) {\r\n\r\n     modCount++;\r\n\r\n     int oldCapacity = elementData.length;\r\n\r\n     if (minCapacity > oldCapacity) {\r\n\r\n         Object oldData[] = elementData; // 此行没看出来用处,不知道开发者出于什么考虑\r\n\r\n         int newCapacity = (oldCapacity * 3)/2 + 1; // 增加新的数组的大小\r\n\r\n         if (newCapacity < minCapacity)\r\n\r\n        newCapacity = minCapacity;\r\n\r\n             // minCapacity is usually close to size, so this is a win:\r\n\r\n             elementData = Arrays.copyOf(elementData, newCapacity);\r\n\r\n     }\r\n\r\n }
\r\n
\r\n
\r\n    Vector中:
\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\nprivate void ensureCapacityHelper(int minCapacity) {\r\n\r\n     int oldCapacity = elementData.length;\r\n\r\n     if (minCapacity > oldCapacity) {\r\n\r\n         Object[] oldData = elementData;\r\n\r\n         int newCapacity = (capacityIncrement > 0) ?\r\n\r\n        (oldCapacity + capacityIncrement) : (oldCapacity * 2);\r\n\r\n         if (newCapacity < minCapacity) {\r\n\r\n        newCapacity = minCapacity;\r\n\r\n         }\r\n\r\n          elementData = Arrays.copyOf(elementData, newCapacity);\r\n\r\n     }\r\n\r\n }
\r\n
\r\n
\r\n

\r\n 关于ArrayList和Vector区别如下:

\r\n
    \r\n
  1. \r\n ArrayList在内存不够时默认是扩展50% + 1个,Vector是默认扩展1倍。
  2. \r\n
  3. \r\n Vector提供indexOf(obj, start)接口,ArrayList没有。
  4. \r\n
  5. \r\n Vector属于线程安全级别的,但是大多数情况下不使用Vector,因为线程安全需要更大的系统开销。
  6. \r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2848, 'win7-is-remove-standby-password', 'Win7取消待机密码', '2012-10-29 05:22:03', '2019-03-25 21:29:22', '   今天开了一会电脑,然后频繁出去了几次,每次回来打开电脑都提示电脑锁定,需要输入待机密码,太烦人,可是突然忘记怎么取消了,摸索了半天,终于找到了解决办法。
\r\n   在桌面右键点击个性化,再点击屏幕保护程序,将在恢复时显示登陆屏幕前面的勾去掉,OK。

\r\n
\r\n    \"\"
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2849, 'nokias-strategy-across-the-three-pillars-collapsed-ceo-elop-must-be-dismissed-i-had-the-brilliant', '诺基亚战略三大支柱全线崩塌,CEO Elop必须被解雇(一)曾经的辉煌', '2012-10-29 05:09:17', '2019-03-25 21:29:22', '

\r\n       诺基亚的现任CEO Stephen Elop两年前正式接掌公司。确切地说,Elope是在2010年的第三季度上任的。在任期的前5个月,Elop没有大幅调整公司现有战略,仅在守成。不 过,Elope比一般守成的CEO做的好很多,三张图可以证明。另外,三张图也能细细给我们讲述诺基亚曾经的辉煌。
\r\n 图一:2010诺基亚分别在4个季度的总营收

\r\n

\r\n \"\"

\r\n

\r\n 注:此图中的总营收仅指来自诺基亚手持设备部门的总营收,未包括来自网络部门的营收。不过,手持设备营收占了公司总营收的大部分,因此不失代表性。
\r\n       由图可知,2010年诺基亚手持设备营收来自功能手机和智能手机,两者各占一半。Elop刚进诺基亚时,全球正在经历我们有生以来最严重的一次经济危机。在 所有和诺基亚合作的设备生产商都遭受损失的情况下,诺基亚的核心业务——手持设备——从未报告过任何损失。但是,在营利方面,公司却遭受严重挫折。 Elop掌权之后,第一件事就是给诺基亚来了一次大瘦身。尽管过程痛苦,但诺基亚却因此在营收、设备销售量、利润方面均上去了,这无论是在功能手机还是智 能手机方面均有体现。
\r\n       在功能手机业务逐渐过渡到智能手机业务方面,因为有了Elop的加入,诺基亚打了一场漂亮仗。在当年的圣诞节假日购物 高潮中,诺基亚第一次在智能手机的销售方面(包括销售量、增长率、营收、利润、利润率各方面)创造了记录。诺基亚智能手机业务的前途似乎光明一片。在当 时,诺基亚功能手机的销售量占公司手持设备销售量的20%,营收却占了公司总营收的30%,而且到年末智能手机利润更是占了公司总利润的40%。要知道, 在当时,市场上智能手机的价格正普遍下滑,诺基亚却逆势增长。在2010的第3季度,也就是Elop在诺基亚的第1个季度,诺基亚发布了3款搭载 Symbian S3操作系统的智能手机,3款加起来卖了500万台。这在诺基亚是一个记录,诺基亚当时还公开宣布无法完全满足全球对其智能手机的需求。
\r\n       Stephen Elop当时曾公开表示,他很喜欢现在的公司,并且对公司的现有战略非常满意。董事长Jorma Ollila也表示,诺基亚不需要新的战略,现有战略是行得通的。雇用Elop的目的是为了解决诺基亚在执行力方面累积的老问题(比如新款设备的发布一推 再推,以往发布的手机机型存在的小问题,诸如此类)。另外,Elop还表示诺基亚和移动运营商的关系是前所未有的好,公司在手机零售业方面的地位无人能 敌。
\r\n 对此,诺基亚的投资人们也乐见其成。过去3年,在前任CEO Olli-Pekka Kallasvuo的领导下,诺基亚的股价下跌了60%。而在Elop掌权的前5个月,诺基亚的股价惊人地提升了11%。2010年的夏天对于诺基亚来说 是一个多事之夏。当时的三家国际评价机构对诺基亚是相当小心。而自Elop带领诺基亚复苏过来之后,三家机构均给予诺基亚接近完美的评分。他们认为,智能 手机是诺基亚皇冠上的一颗明珠。诺基亚拥有大热的Symbian操作系统平台,席卷全球的超级手机N8,在接下来的数周还会推出包括E7在内的数款智能手 机。最棒的是,诺基亚未来的操作系统Meego即将向全世界发布。Meego操作系统基于Linux开发、开源,和Intel、中国移动合作,目的是服务 于诺基亚经后智能机的产品线。当时诺基亚已经有一款智能机搭载上了Meego,而且还有至少3款搭载Meego的智能机已在计划中,预计2011年发布。
\r\n 图2:2010年4季度中,诺基亚智能手机在销售量、营收、利润、利润率方面的表现

\r\n

\r\n \"\"

\r\n

\r\n 注:以第1季度为准,我对后3个季度的数字进行了归一化。

\r\n

\r\n       首先有一个背景知识:当时诺基亚的智能手机具有霸主地位,大大领先于iPhone、黑莓、三星。下面分别看,首先是销售量(Unit Sales)。2010年诺基亚智能手机的销售量每季度都有所增长,而且总得增长量大大高于苹果的iPhone,市场规模比智能手机领域的第2名大了惊人 的2倍,不得了。

\r\n

\r\n 营收(Revenues)方面,虽然还是按季度增长,但没有销售量增长快,并且两者差距在第二季度还有所拉大。长期来看是个不好的预兆。但在Elop上任后,经过对公司的修修补补,公司营收实现了高增长,缩小了和销售量间的差距。

\r\n

\r\n 最 后是利润(Profits)和利润率。两者在第2季度不但没有增长反而下滑,这也造成了当时的诺基亚带来了不少的质疑之声,而这跟之前诺基亚管理层的管理 不善有很大关系。Elop的到来也让诺基亚的利润和利润率不但避免了继续下滑,还在第4季度出现了大幅增长。对于诺基亚来说,这幅图的数字非常漂亮,也预 示着2011年诺基亚将会变得更好。

\r\n

\r\n 最重要的是,这说明诺基亚由功能手机向智能手机 实现了一个漂亮的过渡。漂不漂亮我们拿其它公司对比。在由模拟信号手机向数字信号手机的过渡中,摩托罗拉就失去了统治地位。这是诺基亚的前车之鉴。但幸运 的是,诺基亚不但顺利度过,而且保住了领先位置。而别的同行就没那么幸运了。 摩托罗拉、索尼爱立信、三星和 LG都遭到了打击和损失。摩托罗拉甚至破产了,被分拆了,并卖给了Google。和索尼合资的爱立信也被终结了,把自己50%的股份全部卖给了索尼,让索 尼全资控股。

\r\n

\r\n 图三:2010年诺基亚、苹果、三星各季度智能手机销售量的表现

\r\n

\r\n \"\"

\r\n

\r\n       2010年,大家对于当时的印象可能是,苹果即将赢得智能手机的战争,Android正在瓜分诺基亚的地盘。但事实真是如此吗?当然不是,因为上图的蓝线代表的是诺基亚。2010年的智能手机市场仍然是诺基亚的天下。不仅如此,诺基亚的市场规模还是第2名的2倍。

\r\n

\r\n 这 个2倍是什么概念?我们来打些比喻。汽车领域, Toyota、General Motors、Volkswagen、Fiat、Peugeot-Citroen、 Renault,、Honda、Nissan中任何一家称霸时,市场规模也没有领先2倍之多。唯一干过这件事的是Ford,不过这已是97年前的事了。在 PC领域,. IBM、 HP、 Dell、Compaq、Apple、 Toshiba,也没有任何一家做到了类似诺基亚在智能手机领域如此强大的霸主地位。

\r\n

\r\n       就用户数量,当时诺基亚在全世界拥有14亿的客户。这比Facebook最近宣布的全球10亿用 户还多。分大陆来看,诺基亚手机在欧洲、亚洲、非洲、拉丁美洲、澳洲都是最畅销的手机。唯一在北美的美国,诺基亚由于受到本土7大手机制造商的冲击,偏离 了第一名,但也绝非最后,算中等。而且欣喜的是,诺基亚在美国的这一情况可能会通过和美国最大移动运营商AT&T的合作得到改善。在当时移动行业 最盛大的移动世界大会(Mobile World Congress)上,诺基亚宣布,2011年的1月,AT&T将在美国发售诺基亚的新款旗舰机。

\r\n

\r\n       一切迹象都证明诺基亚在2011年将迎来更辉煌的一年。对于作为CEO的Elop来说,经营一家本就成功的公司也不算难事,并且Elop守成还守的挺好。但是,Elop似乎觉得日子太舒适了,最终放弃了守成,执意宣布了自己的所谓新战略。

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2850, 'nokias-strategy-across-the-three-pillars-collapsed-ceo-elop-must-be-dismissed-ii-came-with-three-legs', '诺基亚战略三大支柱全线崩塌,CEO Elop必须被解雇(二)突然来的三条腿', '2012-10-29 05:06:26', '2019-03-25 21:29:22', '

\r\n     诺基亚在2010年的漂亮仗很大程度上要归功于Elop,他在继续执行诺基亚原有战略的基础上,给诺基亚来了次大瘦身,并把公司在执行力方面的历史 遗留问题妥善的解决了。回顾过去,不少人感叹,如果Elop能继续这样漂亮地守下去,2011年的诺基亚也会光辉灿烂。但是,2011年2月,媒体曝光了 一封Elop给诺基亚内部员工的的邮件——燃烧的平台备忘录,2月11日,Elop强势宣布了基于此备忘录的三条腿新政。

\r\n

\r\n     Elop 的三条腿指的是:功能手机、智能手机的Symbian平台、未来诺基亚的智能手机平台——Windows Phone。坚守老阵地功能手机和Symbian平台不意外,我们意外的是强势入驻诺基亚的Windows Phone。要知道此前诺基亚未来手机平台一直定的是Meego。在和微软合作之前,包括Meego团队在内的整个诺基亚上下可以说都只有一个目标——排 除万难完成基于Meego操作系统设备的研发和生产,并在2011年上市。

\r\n

\r\n     Windows Phone不仅顶了Meego的位置,而且还打算吞掉Symbian。Elop表示,虽然短期而言,Symbian将会继续作为诺基亚的智能手机平台,但 一旦等到诺基亚基于WP的手机发布,Symbian就会逐渐让位于WP,最终消失。此外,功能手机的小块领地也会拱手送给WP。下图生动地展示了Elop 的三条腿新政:

\r\n

\r\n \"\"

\r\n

\r\n     此图在2011年多次被诺基亚官方用于描述其新政。图内,纵轴是三条腿各自所占公司总营收的比例;横轴是时间,但是Elop当时并没有给出战略实行的具体时 间表,只是粗略地表示,由Symbian到WP的整个过渡可能会持续到2012年末或2013年初。另外,董事长Jorma Ollila表示,基于WP平台的诺基亚手机可能会在2012年春在全球的各大市场上市。

\r\n

\r\n     现在是2012年,诺基亚基于WP的手机Lumia也已经上市了,我们回过头来验收一下这一计划。今年6月30日,诺基亚今年第二季度的财报显示,公司基于WP平台的智能机已经与基于Symbian平台的智能机取得了同样的营收。把此时间点对应到上图:

\r\n

\r\n \"\"

\r\n

\r\n 为了具体讨论这张图,我们再来一张图,关于图中的Symbian部分:

\r\n

\r\n \"\"

\r\n

\r\n 图 中白色部分是与Elop承诺在Symbian平台实现的营收相比,诺基亚在Symbian上亏损的部分,价值155亿美元。历史上,诺基亚的智能手机业务 从未出现过亏损。而Elop的三条腿新政后,诺基亚的智能手机业务亏了,而且越亏越严重,自此之后从未有一个季度在智能机方面实现营利。

\r\n

\r\n 一条腿折了,再看另一条腿——功能机:

\r\n

\r\n \"\"

\r\n

\r\n     要知道在2010年,诺基亚的功能手机业务的营收增长为23%。而新政之后,意想不到的事情发生了,功能手机也亏了64亿美元。事实上,Elop也曾公开表 示对诺基亚功能机业务下跌的意外。WP抢占的只是诺基亚的智能手机平台,按道理影响的只是Symbian手机的销量,为何功能机也跟着遭殃呢?试想一下, 如果你的CEO在一个荒谬的燃烧的平台备忘录里,公开的宣称自己的产品是垃圾,这势必会影响诺基亚整个手机产品线的销量。而且此事最终还令诺基亚遭到了零售商的抵制,诺基亚从此在销售通路上屡出状况,经常遭到来自零售商和运营商的阻碍。

\r\n

\r\n     诺基亚和零售商、运营商之间的关系恶化,这不是空谈。在今年4月的股东大会上,Elop也承认,在全球范围内,存在运营商诺基亚和微软的抵制。同 时,Elop表示,诺基亚手机销量下滑的原因不在与手机本身,手机的设计和质量都没问题,问题主要源自诺基亚与零售商、运营商之间关系的恶化。全球的评测 机构Moody’s 和S&P对诺基亚的评测也证实了Elop的这一言论。

\r\n

\r\n     第二条腿折了,最后一条腿可千万不能再折了,因为这是Elop新政的核心,Elop做的一切都是为了它。通过和微软的合作,Elop和微软CEO Steve Ballmer许诺,未来的世界会出现除iOS、Android之外的第三大生态系统。现在来看看这条腿:

\r\n

\r\n \"\"

\r\n

\r\n    虽然诺基亚的旗舰机lumia 920在欧洲广受欢迎,但据诺基亚刚刚发布的财报,第三季度,诺基亚Lumia系列手机销量降至290万部,低于分析师预期的293万部,也大大低于上一季度售出的400万部。目前为止,诺基亚已在WP平台损失了近25亿美元。

\r\n

\r\n    行业分析师认为,lumia系列销量走低主要还是因为微软给诺基亚的背后一刀。诺基亚和微软合作基于的是WP7平台,整个Lumia产品线搭载的也是WP7 操作系统。但是,在今年6月20日,微软正式发布Windows Phone 8,宣布WP7生命周期终止,正式退出市场,同时还宣布所有WP7手机全部不能升级到WP8系统。这当头一棒是彻底把诺基亚打懵了,之后诺基亚Lumia 系列无论是在销量还是价格上都大受影响。照此看来,诺基亚的这最后一条最关键的腿也算是折了。而Elop本人也在最近接受AllthingsD采访时,承认诺基亚过去本可在WP平台上做的更好。不过Elop同时也表示,产品没问题,诺基亚不会改变策略,未来诺基亚还会坚守WP平台,并且相信这会是一笔好生意。

\r\n

\r\n    看到这里大家可能会觉得Elop简直是个疯子,或者被虐狂,微软这么给了他背后一刀都还不死心。而且为什么一开始Elop就这么执着于WP呢?为什么 Elop那么讨厌Meego和Symbian呢?到底Elop是出于什么样的动机制定看似“傻逼”的三条腿政策的?难道Elop真疯了?还是有别的原因? 请关注即将推出的《诺基亚战略三大支柱全线崩塌,CEO Elop必须被解雇(三)三条腿上的思考》

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2851, 'nokias-strategy-across-the-three-pillars-collapsed-ceo-elop-must-be-dismissed-c-thoughts-on-three-legs', '诺基亚战略三大支柱全线崩塌,CEO Elop必须被解雇(三)三条腿上的思考', '2012-10-29 04:52:07', '2019-03-25 21:29:22', '

\r\n 为了防止Ahonen一面之词,也为了公平起见,我们来听听Elop在三条腿上的思考。

\r\n

\r\n 首先,诺基亚当时在智能手机市场有颓势?不是说2010年的诺基亚是一片飘红吗?Elop认为那只是表象。在燃烧的平台备忘录里面,Elop这样比喻了诺基亚当时所处的境地:Elop认为,诺基亚就好像在北海石油平台上工作的工人,一次意外让工人四周都是熊熊燃烧的烈火和浓烟。为了求生,工人必须破釜沉舟、跳海自救。一片飘红的诺基亚原来四周飘的都是足以致命的烈火?

\r\n

\r\n 是 的。Elop认为,诺基亚当时无论是在高、中、低端手机领域都面临强大的竞争。2007年,苹果重新定义了智能手机,发布了第一代iPhone,并且正试 图打造一个异常强大而封闭的生态系统,意欲颠覆整个市场。到2010年,苹果的这一雄心壮志已初具规模,2010年第四季度的年市盈增长率达到了78%。 反观诺基亚,当时还没有一款能够和iPhone媲美的高端智能机。Elop并不认为诺基亚内部没有类似iPhone的天才创新,Meego就被寄希望于赢 得未来高端智能机平台。但是因为这样那样原因,开发速度太慢。以目前速度,到2011年底,诺基亚或许只能推出一款Meego手机。这不得不让Elop考 虑其它更快速的可能性。

\r\n

\r\n Android的崛起也让诺基亚不容小视。自2008年正式发布以来,两年的时间,Android平台成功地吸引了 应用开发者、服务提供商和硬件厂商。Android从高端入门,目前正在赢得中端市场,并且很快他们会转向100欧元以下的手机。Google已经成为一 支举足轻重的力量,在核心中融入了大量业内创新。

\r\n

\r\n 在低端市场,中国一直是诺基亚全球最大的市场。但是,2008年,来自台湾的全球消费者 IC片组领航者——联发科技(MediaTek),开始提供全套的手机芯片组参考设计,这让中国深圳的厂商可以快速生产手机。一名诺基亚员工曾半开玩笑地 说,这些贴牌的中国低端手机厂商连制作一段PPT的时间都用不了就能开发出一个手机。而且,当时全球三分之一以上的手机来自联发科技的生态圈,侵蚀了诺基 亚在新兴市场的份额。

\r\n

\r\n 基于这样一个市场判断,Elop在诺基亚的生命历程中制造了一个重大的转折点,做出了三大决定:放弃Symbian、 放弃Meego、拥抱WP。目前来看,大众认为这三大决定是在把诺基亚搞死,证明了Elop是微软来的Elop。的确,在去诺基亚之前,Elop在微软当 了两年高管。但这绝不能成为他附庸微软、搞死诺基亚的理由。他好不容易通过诺基亚站在了科技界的最前沿,我想他不会浪费这次机会。话不多说,分别来看看 Elop是如何做出这三大决定的。

\r\n

\r\n 放弃Symbian

\r\n
\r\n

\r\n Symbian,智能手机系统领域曾经的当之无愧的老大。然而iPhone出现了,塞班的优势似乎只剩下价格了;接着,安卓出现了,塞班的价格优势不见了。Symbian似乎成了怀旧者的专属。

\r\n
\r\n

\r\n 这句话引自《中国经济周刊》作者撰稿人王辰越的文章《智能手机系统之4 塞班:从霸主到弃子》,很具概括性地总结了Symbian的一生,也提醒我们为什么Elop要如此坚决地放弃Symbian。

\r\n

\r\n 可 以说Symbian系统是含着金汤匙长大的。研发Symbian系统的塞班公司成立于1998年6月,由当时包括爱立信、诺基亚、松下、摩托罗拉在内的一 群响当当的手机厂商共同投资建立,意欲打造一个强大的Symbian联盟。如其所愿,强大的Symbian联盟自2000年开始逐步形成。2000年,爱 立信发布了全球首款搭载Symbian操作系统的手机——爱立信R380。此后,索尼、三洋、富士通、索尼爱立信也相继推出了自己的Symbian手机。 一时间Symbian几乎将全球所有著名的手机厂商囊括殆尽。强大的联盟让Symbian手机在智能手机领域的市场份额在2003年达到了可怕的 66.6%。不仅如此,2004年2月,诺基亚宣布收购了Psion公司持有的价值大约1.357亿英镑的塞班公司股权,成为了塞班公司最大的股 东,Symbian系统的命运从此也真正紧密地和诺基亚连在了一起。手机生产商老大联手智能机操作系统老大,风光一时无两。

\r\n

\r\n 盛过之后很可能 是衰。2007年初,iPhone闪亮登场。2007年末,Google展示了Android操作系统。两者的到来宣告了同一件事——“智能”手机的“智 能”可不是Symbian想的那么简单。虽然Symbian系统已经具备了目前智能手机的很多功能,但是说到底Symbian在编写之初是冲着打电话时信 号通畅去的,对于很多现今流行的智能机功能的支持存在先天不足,有生搬硬套之嫌。

\r\n

\r\n 在最初的时候,也就是1999年3月,刚成立9个月的塞班 公司推出了Symbian5.0操作系统。这个操作系统在当时人们的眼里已经非常“智能”了。它集成了通信网络、无线文字、网页浏览、电子邮件等功能,支 持Java应用,能够运行小型的第三方软件,比微软的WindowsCE更易用。也因此,同年,塞班公司被美国媒体评为“综合评定最佳”和“最具长期潜 力”的公司。但是,苹果和Android引领的新智能机时代到来之后,人们逐渐意识到智能机除了能够上网、看邮件之外,还可以有超大电容屏、各种手势触 控、各种好玩的应用。而对触控屏、多媒体、应用扩展性的支持恰恰是Symbian的软肋。在同PC和互联网的交互方面,Symbian也先天不足。

\r\n

\r\n Symbian 系统在新智能手机时代表现出的先天不足在苹果和Android的日渐繁荣中逐步显现。这也是为什么在2010年第二季度,诺基亚在数字一片飘红的情况下, 利润率却下降了40%的一个重要原因。但是,Symbian给诺基亚带来的曾经的辉煌限制住了诺基亚的手脚。在这种颓势下,诺基亚当时的CEO 康培凯却仍寄希望于Symbian。在2010年7月,康培凯宣布将Symbian定位于中低端市场,希望通过降价策略提升Symbian手机的市场份 额,准备在未来几年内销售5000万部搭载Symbian的诺基亚手机。同时也打算将Symbian开源,让开发者为其贡献内容。但是,就价格来讲,随着 手机在全球的普及,价格正逐渐走下神坛,不再是左右消费者购买决定的最关键因素,重要的是用户体验。将Symbian开源着实也解决不了Symbian先 天不足的根本缺陷。而另一方面,Android市场的崛起却在中低端市场给了Symbian很大的压力。而且无论是开发者和消费者都有越来越爱 Android的趋势。

\r\n

\r\n 两个月过后,康培凯离职了。虽然当时诺基亚董事会已经传出要放弃Symbian,但这跟力挺Symbian的康培凯 在9月份离职没有必然联系。当时康培凯离职的最主要原因还是其带领的诺基亚利润率大幅下滑,并且无法提出任何有效改善销售和财务状况的措施。不过,此后上 任的新CEO Elop可能在到任之初就有把放弃Symbian作为拯救诺基亚的重要一步。这也可能是为什么在Elop上任前5个月对诺基亚实行大瘦身,让诺基亚摆脱财 政问题之后,Elop仍然不满现状,决定对诺基亚实行大幅改革。可能从最开始,Elop就不认为诺基亚的根本问题在执行力不足。Elop可能一开始就意识 到,如果光靠老旧的Symbian系统和功能手机,诺基亚在未来无法真正和苹果、Android抗衡。因此,诺基亚必须在新智能手机时代找到自己新的出 路。从这个角度讲,读者大概能够比较理解为什么Elop在2011年2月,在刚刚把诺基亚恢复到“辉煌”之后,还毅然决然地宣布放弃Symbian。

\r\n

\r\n 现 在来看,放弃Symbian是诺基亚的必经之路。不过,放弃Symbian必须是逐步的,因为Symbian截至到目前仍然是诺基亚智能手机领域的主力 军。在诺基亚转战到另一平台(无论是Meego还是WP,这里暂不讨论)之前,Symbian必须能够给诺基亚一个平稳的过渡。这一点Elop也意识到 了,并且给这个过渡期规划了1.5亿台Symbian机的销量。但是,事与愿违,自从Elop宣布逐步放弃Symbian之后,不只是Symbian,诺 基亚的整个手机业务都开始下滑。目前分析认为,这主要是Elop在政策实行上的问题——过早宣判了Symbian的死刑,造成奥斯本效应。事实上,诺基亚由老旧的Symbian平台过渡到一个符合新智能手机时代要求的平台,这是诺基亚必经的一个转型期。Elop放弃Symbian的决定算是没错,错的是Elop的高调处事方式。早早的预告Symbian即将终结,这无论对于开发者还是消费者都是一个重挫。

\r\n

\r\n 由 于过早宣布Symbian的死刑,从2011年下半年开始,很多开发者对于Symbian应用的开发已经开始停滞,应用在诺基亚Ovi上的下载量也大幅下 降。2010年诺基亚Ovi商店每天约有100万的下载量,到2011年上半年这个量增长到每天500万,在2011年底诺基亚宣布放弃Symbian品 牌后,应用下载量逐步下滑到了每天不足200万。而在诺基亚手机的销量方面,上一篇《诺基亚战略三大支柱全线崩塌,CEO Elop必须被解雇(二)突然来的三条腿》中,前高管Tomi Ahonen已经把数据一一罗列,并以此痛批Elop。

\r\n

\r\n 可 以说,Elop在Symbian上的高调处事方式加剧了诺基亚在转型期的阵痛,同时也为其过渡到WP平台“赢得”了更短的准备期。Symbian的事已经 造成,无法挽回,不过诺基亚还是幸运地经受住了这一折腾。虽然目前诺基亚还是处于亏损状态,但至少还没死,而且其基于新平台WP的Lumia也已经出了7 部了。目前关系诺基亚未来是否能复苏的关键已经不再是Symbian这事,而是其是否投奔对了WP平台。关于这点,我将在本系列的第5期和大家详细讨论。 而在接下来的第4期中,我将和大家聊聊Meego,这个至今都让很多诺基亚员工无法忘怀的操作系统。另外,很多诺基亚迷也对Meego诞下的唯一一颗珍珠 ——N9——念念不忘。下期我们就来看看Meego到底有什么魅力,而Elop为何又执意要放弃Meego。

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2852, 'windows-8-microsofts-declining-popularity-mobile-storm-three', 'Windows 8止微软颓势,移动风暴刮出三足鼎立', '2012-10-24 12:08:16', '2019-03-25 21:29:22', '      Windows 8是微软寄予厚望的重头产品,今天正式登陆中国。不过Forrester的分析师预测,Windows 8的推出只能稳定微软在PC领域的统治地位,但在移动风暴的席卷之下,操作系统市场微软、Google、苹果三足鼎立已是大势所趋。 Forrester在《未来五年的Windows》报告中预测了Windows 8的推广进程。报告认为Windows 8 2013年的起步会较慢,因为传统PC用户会推迟自己的升级时间。这主要是由于Windows 8的全新架构给用户造成困惑,且该操作系统在跨设备上存在体验的不一致,需要较长的过渡时间。但是渴望上手Windows 平板电脑的买家则会向Windows 8敞开怀抱。到2014年Windows 8将会稳住阵脚,争取到较多用户。
\r\n
\r\n \"\"\r\n
\r\n 个人设备销量预测(按OS)
\r\n
\r\n      微软在PC领域仍是绝对的主角。其市场份额一直维持在95%左右,苹果过去5年在Mac上的努力无法撼动微软的优势。分析预计,到2016年,微软在PC的份额仍能维持在90%左右。 不过,由于智能手机、平板电脑的增长狂潮,微软已经无力掌控整个操作系统市场,其在2012年的市场份额(含PC、智能手机、平板电脑)已经降至30%。分析预计,到2016年,微软在智能手机OS的份额为14%,平板电脑OS的份额为27%(这已经是一个相当不错的数字,要比NDP Display Search7%的预测数字乐观很多)。智能手机OS的霸主为Google Android,而平板电脑OS则是苹果的iOS拔得头筹。操作系统市场三足鼎立之势已经确立。\r\n
\r\n \"\"\r\n
\r\n OS份额比例预测
\r\n
\r\n      在瞬息万变的技术市场里,这场三国演义谁会笑到最后?也许没人能回答这个问题。
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2853, 'articles-by-the-english-word-enhanced-b', '考研英语单词强化(二)', '2012-10-24 01:15:59', '2019-03-25 21:29:22', '\"\"
\r\n
\r\n\"\"
\r\n
\r\n\"\"
\r\n
\r\n\"\"
\r\n
\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2854, 'articles-by-the-english-words-to-strengthen-a', '考研英语单词强化(一)', '2012-10-24 00:46:08', '2019-03-25 21:29:22', '\"\"
\r\n
\r\n
\r\n\"\"
\r\n
\r\n\"\"
\r\n
\r\n\"\"
\r\n
\r\n\"\"
\r\n
\r\n\"\"
\r\n
\r\n\"\"
\r\n
\r\n\"\"
\r\n
\r\n\"\"
\r\n
\r\n\"\"
\r\n
\r\n\"\"
\r\n
\r\n\"\"
\r\n
\r\n\"\"
\r\n
\r\n\"\"', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2855, 'windows-api-messagebox-style-gallery', 'Windows API中MessageBox样式集锦', '2012-10-20 08:31:42', '2019-03-25 21:29:22', '

\r\n MessageBox(NULL,TEXT("HelloWorld"),TEXT("Hello"),MB_OK);
\r\n \"\"
\r\n
\r\n MessageBox(NULL,TEXT("HelloWorld"),TEXT("Hello"),
MB_OKCANCEL)
\r\n \"\"
\r\n
\r\n MessageBox(NULL,TEXT("HelloWorld"),TEXT("Hello"),
MB_ABORTRETRYIGNORE);
\r\n \"\"
\r\n
\r\n MessageBox(NULL,TEXT("HelloWorld"),TEXT("Hello"),
MB_YESNOCANCEL);
\r\n \"\"
\r\n
\r\n MessageBox(NULL,TEXT("HelloWorld"),TEXT("Hello"),
MB_YESNO);
\r\n \"\"

\r\n
\r\n MessageBox(NULL,TEXT("HelloWorld"),TEXT("Hello"),MB_RETRYCANCEL);
\r\n \"\"
\r\n
\r\n MessageBox(NULL,TEXT("HelloWorld"),TEXT("Hello"),MB_CANCELTRYCONTINUE);
\r\n \"\"
\r\n
\r\n MessageBox(NULL,TEXT("HelloWorld"),TEXT("Hello"),MB_ICONHAND);
\r\n \"\"
\r\n
\r\n MessageBox(NULL,TEXT("HelloWorld"),TEXT("Hello"),MB_ICONEXCLAMATION);
\r\n \"\"
\r\n
\r\n MessageBox(NULL,TEXT("HelloWorld"),TEXT("Hello"),MB_ICONASTERISK);
\r\n \"\"
\r\n
\r\n MessageBox(NULL,TEXT("HelloWorld"),TEXT("Hello"),MB_USERICON);
\r\n \"\"
\r\n
\r\n MessageBox(NULL,TEXT("HelloWorld"),TEXT("Hello"),MB_ICONWARNING);
\r\n \"\"
\r\n
\r\n MessageBox(NULL,TEXT("HelloWorld"),TEXT("Hello"),MB_ICONERROR);
\r\n \"\"
\r\n
\r\n MessageBox(NULL,TEXT("HelloWorld"),TEXT("Hello"),MB_ICONINFORMATION);
\r\n \"\"
\r\n
\r\n MessageBox(NULL,TEXT("HelloWorld"),TEXT("Hello"),MB_ICONSTOP);
\r\n \"\"
\r\n
\r\n MessageBox(NULL,TEXT("HelloWorld"),TEXT("Hello"),MB_DEFBUTTON1);
\r\n \"\"
\r\n
\r\n MessageBox(NULL,TEXT("HelloWorld"),TEXT("Hello"),MB_DEFBUTTON2);
\r\n \"\"
\r\n
\r\n MessageBox(NULL,TEXT("HelloWorld"),TEXT("Hello"),MB_DEFBUTTON3);
\r\n \"\"
\r\n
\r\n MessageBox(NULL,TEXT("HelloWorld"),TEXT("Hello"),MB_DEFBUTTON4);
\r\n \"\"
\r\n
\r\n MessageBox(NULL,TEXT("HelloWorld"),TEXT("Hello"),MB_APPLMODAL);
\r\n \"\"
\r\n
\r\n MessageBox(NULL,TEXT("HelloWorld"),TEXT("Hello"),MB_SYSTEMMODAL);
\r\n \"\"
\r\n
\r\n MessageBox(NULL,TEXT("HelloWorld"),TEXT("Hello"),MB_TASKMODAL);
\r\n \"\"
\r\n
\r\n MessageBox(NULL,TEXT("HelloWorld"),TEXT("Hello"),MB_HELP);
\r\n \"\"
\r\n
\r\n MessageBox(NULL,TEXT("HelloWorld"),TEXT("Hello"),MB_NOFOCUS);
\r\n \"\"
\r\n
\r\n MessageBox(NULL,TEXT("HelloWorld"),TEXT("Hello"),MB_SETFOREGROUND);
\r\n \"\"
\r\n
\r\n MessageBox(NULL,TEXT("HelloWorld"),TEXT("Hello"),MB_DEFAULT_DESKTOP_ONLY);
\r\n \"\"

\r\n

\r\n
\r\n MessageBox(NULL,TEXT("HelloWorld"),TEXT("Hello"),MB_TOPMOST);
\r\n \"\"
\r\n
\r\n MessageBox(NULL,TEXT("HelloWorld"),TEXT("Hello"),MB_RIGHT);
\r\n \"\"
\r\n
\r\n MessageBox(NULL,TEXT("HelloWorld"),TEXT("Hello"),MB_RTLREADING);
\r\n \"\"
\r\n
\r\n MessageBox(NULL,TEXT("HelloWorld"),TEXT("Hello"),MB_SERVICE_NOTIFICATION);
\r\n \"\"
\r\n
\r\n MessageBox(NULL,TEXT("HelloWorld"),TEXT("Hello"),MB_SERVICE_NOTIFICATION_NT3X);
\r\n \"\"
\r\n
\r\n MessageBox(NULL,TEXT("HelloWorld"),TEXT("Hello"),MB_TYPEMASK);
\r\n \"\"
\r\n
\r\n MessageBox(NULL,TEXT("HelloWorld"),TEXT("Hello"),MB_ICONMASK);
\r\n \"\"
\r\n
\r\n MessageBox(NULL,TEXT("HelloWorld"),TEXT("Hello"),MB_DEFMASK);
\r\n \"\"
\r\n
\r\n MessageBox(NULL,TEXT("HelloWorld"),TEXT("Hello"),MB_MODEMASK);
\r\n \"\"
\r\n
\r\n MessageBox(NULL,TEXT("HelloWorld"),TEXT("Hello"),MB_MISCMASK);
\r\n \"\"
\r\n  

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2856, 'windows-8-will-bring-microsoft-into-the-tablet-age', 'Windows 8将微软带入平板时代', '2012-10-20 05:27:59', '2019-03-25 21:29:22', '

\r\n 微软Windows操作系统正在经历自1995年以来最大的一次革新,即使是最忠实的一批用户也可能认不出Windows 8,这款操作系统将于10月26日面世。

\r\n

\r\n 体验陌生的“开始屏”

\r\n

\r\n 一打开Windows 8的界面你就会发现,这完全是个陌生的Windows界面。原先熟悉的桌面变成了现代感十足的大型滚动区块式图标和更加简洁、全屏显示的应用程序,而这一切都是由平板和智能手机“唆使”的。Windows 8的“开始屏”代替了“开始按钮”。“开始屏”功能十分强大,它是一个完整的计算系统,拥有独立的应用控制权,可以掌控整个显示屏内容。之前的“开始按钮”和传统Windows应用程序也并未消失,Windows 8的“开始屏”就像一个应用程序,你想使用哪个程序只需轻轻点击即可。

\r\n

\r\n 笔者认为微软的这一步很大胆,Windows 8的界面友好,使用效果也很流畅。但Windows 8的触摸屏实在不得不让人联想到平板电脑,现在说Windows 8将微软带入了平板时代还为时尚早,毕竟微软推广Windows 8需要做的工作还有很多,Windows 8新版应用开发就是个很棘手的问题。当然也有好消息,微软的Windows 8可以在PC或平板电脑上运行,而苹果iPad和Mac采用的操作系统是完全不同的。

\r\n

\r\n Windows 8如何混淆PC和平板

\r\n

\r\n \"\"

\r\n

\r\n Windows 8采取双环境同时运行的战略,一方面方便用户,但两种工作方式之间切换会让传统PC用户感到头晕。无论新环境还是旧环境都可以通过触摸或鼠标键盘操作,唯一的区别就是用户偏好问题。在这个问题上微软赌了一把,微软认为这种混淆不会持续很长时间,因为微软在传统PC上能够运行的Office软件目前并不支持iPad与Android,而这也是传统PC能够继续存在的“救命稻草”。

\r\n

\r\n 不同的版本引发的疑惑

\r\n

\r\n \"\"

\r\n

\r\n  

\r\n

\r\n 其实,Windows 8还有别的地方会让用户疑惑,Windows 8将会推出两个版本。一个版本支持运行英特尔处理器的PC;另一个版本专为微软平板推出,名叫RT。前一个版本不仅能运行最新的Windows 8应用,还兼容完整的传统程序。而后一版本就不是那么完美了,对传统程序的支持较少。比如Office软件,在RT版去除了Outlook,若想使用,只能去微软在线商店下载,而这与iPad应用商店如出一辙。

\r\n

\r\n 微软其实也拿出了一套解决方案,就是自己推出Surface平板电脑。与运行Windows 8和Windows RT的平板电脑厂家展开直接竞争,曾经“甜蜜”马上就会烟消云散。

\r\n

\r\n Windows 8诸多新特性

\r\n

\r\n 笔者试用了微软Surface平板电脑,结果发现Windows 8的“开始屏”非常顺滑靓丽。消息提示、邮件显示和图片展示方式都很方便快捷,足以与iPad和Android平板电脑抗衡。

\r\n

\r\n \"\"

\r\n

\r\n Windows 8新增了一个创新性十足的“Charms”控制功能,点击屏幕右侧即可弹出Charms。如果你的设备不支持触摸屏,把鼠标移到屏幕右上角即可激活Charms。Charms中包含搜索、设置、共享、设备和返回“开始屏”功能。Windows 8还支持在屏幕中同时打开多个窗口操作,可以自由移动组合。

\r\n

\r\n Windows 8应用程序亮点多多

\r\n

\r\n \"\"

\r\n

\r\n Windows 8的诸多应用程序是令人印象深刻的,如Photos应用,不仅能够显示电脑中存储的照片,还能同时显示用户在Facebook、Flickr和微软SkyDrive云端储存的照片。People应用不仅显示联系人信息,还能及时同步联系人在社交网络上的状态更新。

\r\n

\r\n Mail应用有点让人失望,缺乏统一收件箱和单一显示未读邮件的文件夹,也没有最常联系人的邮件文件夹。微软应用商店作为Windows 8应用的唯一“提供场所”也是刚刚起步,缺少很多常用的第三方应用。应用商店中已有支持Kindle和Netflix的应用,但尚未发现Dropbox、Facebook和Twitter等应用。微软方面表示,在下周Windows 8正式发布时,会加入更多的流行应用。

\r\n

\r\n Windows 8各版本售价

\r\n

\r\n \"\"

\r\n

\r\n Windows RT是与设备内嵌配套销售的。高端版本名为Pro,用户可单独购买,也可升级系统到Pro。微软目前尚未披露Windows 8操作系统的具体售价,不过在未来几个月内,用户可以花40美元下载Windows 8,或是花70美元购买DVD光盘版。在今年6月2日至明年1月31日期间购买预装Windows电脑的用户,只需支付15美元即可升级至Windows 8。但对没有触摸屏的用户而言,升级到Windows 8并不是一个好的选择。Pro也许更适合企业用户使用,家庭消费版就叫Windows 8,微软尚未透露其具体售价。

\r\n

\r\n 结语

\r\n

\r\n 微软为Windows“洗心革面”还是值得肯定的,而且微软还将继续维护“传统优势项目”,以巩固自己的势力范围。但随着Windows 8的强势来袭,也许我们迟早要向传统的Windows桌面说再见,然后说一声:Windows 8,你好!(编译:朱慧涛)

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2857, 'vs2010-mfc-font', 'VS2010修改MFC菜单栏的字体', '2012-10-18 18:54:52', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

VS2010默认生成的MFC程序菜单栏字体很模糊,在CMainFrame::OnCreate函数中加入以下代码即可:

  1. //设置正常字体  
  2. LOGFONT lf;  
  3. afxGlobalData.fontRegular.GetLogFont(&lf);  
  4. afxGlobalData.fontRegular.DeleteObject();  
  5. lf.lfHeight =-12;  
  6. lstrcpy(lf.lfFaceName, _T("宋体")); // using without style office 2007  
  7. afxGlobalData.fontRegular.CreateFontIndirect(&lf);  
  8.  
  9. //设置加粗的字体  
  10. afxGlobalData.fontBold.GetLogFont(&lf);  
  11. afxGlobalData.fontBold.DeleteObject();  
  12. lf.lfHeight =-12;  
  13. lstrcpy(lf.lfFaceName, _T("宋体"));  
  14. afxGlobalData.fontBold.CreateFontIndirect(&lf);  
  15.  
  16. afxGlobalData.fontTooltip.GetLogFont(&lf);  
  17. afxGlobalData.fontTooltip.DeleteObject();  
  18. lf.lfHeight =-12;  
  19. lstrcpy(lf.lfFaceName, _T("宋体"));  
  20. afxGlobalData.fontTooltip.CreateFontIndirect(&lf);  
  21.  

在你的对话框的头文件中, 在消息映射中添加 afx_msg void OnNcPaint();

在你的对话框的cpp文件中, 在消息映射中添加 ON_WM_NCPAINT()

然后再添加这个消息响应函数:

  1. void CXXXDlg::OnNcPaint()  
  2. {  
  3. CDialog::OnNcPaint();  
  4. CDC* pDC = GetWindowDC();  
  5. int x = GetSystemMetrics(SM_CXSIZE)+GetSystemMetrics(SM_CXBORDER)+GetSystemMetrics(SM_CXDLGFRAME);  
  6. int y = GetSystemMetrics(SM_CYDLGFRAME);  
  7. CRect CapRct;  
  8. GetWindowRect(&CapRct);  
  9. int y1 = GetSystemMetrics(SM_CYICON)-GetSystemMetrics(SM_CYDLGFRAME)-GetSystemMetrics(SM_CYBORDER);  
  10. int x1 = CapRct.Width ()- GetSystemMetrics(SM_CXSIZE)-GetSystemMetrics(SM_CXBORDER)-GetSystemMetrics(SM_CXDLGFRAME);  
  11.  
  12. CapRct.left = x;  
  13. CapRct.top = y;  
  14. CapRct.right = x1;  
  15. CapRct.bottom = y1;  
  16.  
  17. //pDC->FillSolidRect(&CapRct,RGB(0,0,0));  
  18. CFont* pCurFont = GetFont();  
  19. LOGFONT lf;  
  20. pCurFont->GetLogFont (&lf);  
  21. lf.lfItalic = TRUE;  
  22. lf.lfWeight = FW_BOLD;  
  23. lf.lfHeight = 18;  
  24. strcpy(lf.lfFaceName ,"Arial");  
  25.  
  26. CFont capfont ;  
  27. capfont.CreateFontIndirect (&lf);  
  28. pCurFont = pDC->SelectObject (&capfont);  
  29. pDC->SetBkMode (TRANSPARENT);  
  30. pDC->SetTextColor (GetSysColor(COLOR_CAPTIONTEXT));  
  31.  
  32. pDC->DrawText ("My Caption" , &CapRct, DT_SINGLELINE | DT_CENTER | DT_VCENTER); //最好定义一个m_strCaption类成员  
  33.  
  34. ReleaseDC(pDC);  
  35. }  
  36.   
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2858, 'google-has-great-potential-in-open-source-cloud-google-app-engines-most-popular', '谷歌在开源云中潜力巨大 Google App Engine最受欢迎', '2012-10-17 08:14:19', '2019-03-25 21:29:22', '

\r\n
\r\n       正如OpenStack、CloudStack和Eucalyptus,现在有很多的开源平台在数据中心建立和亚马逊一样的云服务,他们在近几年都受到了大量的注意力。但确实有公司真的已经准备好使用它们了吗?      
\r\n 前段时间,Zenoss公司发布了一项关于开源云计算采用的民意调查。Zenoss对它的10万名客户进行了调查,其中包括系统管理员、开发人员和其他   IT专业人士,并且得到了600个回应。
\r\n       大多数受访者(82.9%)没有使用一个开源的云系统,但56.9%的人表示他们正在考虑在未来的两年部署一个或多个开源运系统。其中,62.8% 的人正在考虑OpenStack,46.8%考虑Apache CloudStack、只有23.8%考虑Eucalyptus。
\r\n       受访者希望一个 开源的云系统在质量和灵活性上进行突破,但他们也很关注开放标准和围绕技术的业界发展。至于为什么他们会想要使用一个开源系 统,60.1%的人因为灵活性,56%的人提到了开放标准和API,51.3%的人则是因为资金。在一个开源云最重要的标准方面,75.5%认为是“效率 和性能的虚拟化技术”,64.2认为是“社区生态系统质量”,51.9%认为是“项目使用的一个首选的开源许可(Apache、GPL等等。)”。
\r\n       在那些不使用一个开源云的受访者中,38.2%的受访者表示技术还未成熟是最其没有使用的首要原因。其他的原因是缺乏支持(30.8%)和安全(29.2%)。随着这些项目的成熟和各种公司在商业化继续努力,这些问题可能会得到解决。
\r\n       Zenoss 还被问及平台即服务(PaaS),也被称为云平台。大多数(83.4%)没有使用PaaS,只有30.3%是感兴趣的。16.6%的使 用已经PaaS,谷歌应用程序引擎是最受欢迎的有51.1%使用它,其次是微软Azure Cloud Foundry以18.9%和15.6%。
\r\n       Zenoss 对平台即服务(PaaS)也进行了调查。大多数人(83.4%)不使用PaaS,只有30.3%的人感兴趣。16.6%的人使用已经了 PaaS,Google App Engine是最受欢迎的PaaS,有51.1%的人使用它,其次是微软Azure(18.9%)和Cloud Foundry(15.6%)。
\r\n       那些正在考虑PaaS,但还没有使用的人中,最感兴趣的是Google App Engine(39.9%),其次是Cloud Foundry(17.6%)。
\r\n 值得注意的是Zenoss的用户群并不代表所有云计算市场,并且受访者也可能不足以代表Zenoss的所有用户。但是该调查确实给了我们一个难得的机会,让我们看到了用户的真实想法。
\r\n
\r\n        本文来自:www.csdn.net。
\r\n  

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2859, 'good-programmers-should-be-familiar-with-a-couple-of-programming-languages', '好的程序员应该熟悉的几门编程语言', '2012-10-17 00:33:50', '2019-03-25 21:29:22', '

\r\n   如果想成为一个好的程序员,甚至架构师、技术总监等,显然只精通一种编程语言是不够的,还应该在常见领域学会几门编程语言,正如我们要成为高级人才不仅要会中文还要会英文,甚至还要会德文、俄文一样,其实是每一种语言都给人另一种思维方式,编程语言也一样。

\r\n

\r\n    每种架构CPU都有自己的汇编语言,如果不涉及很底层的修改,了解X86的即可,理解一下机器语言的工作方式,便于优化核心代码。

\r\n

\r\n   几乎适用于各个领域,应该是目前用途最广泛的编程语言(开发人数不是最多,但涉及到的领域、项目数量应该是最多的,目前尚没有数据支撑这一 点)。本人接触到的第一门编程语言,除了C++也是最喜欢的一本编程语言,非常美的语言,无论从其语法、编程思想、运行效率、灵活性等都有着无五伦比的优 势,虽然没有直接支持面向对象的语言特性,但很多项目也将面向对象的思想应用于C语言应用的开发。C语言出生40余年仍然风糜世界,并被大量应用于各个领 域、各种项目,这本身就是一个奇迹,包括后来的C++、Java、C#、Javascript 等等众多主流的编程语言都深受其影响。

\r\n

\r\n     学好C语言本身其实并不难,但C语言是与操作系统近距离工作的一种编程语言,由于其运行环境的复杂性导致了写好它必须先熟悉其环境,所以要求编程者对操作 系统乃至硬件都要非常熟悉,所以学C语言的人感觉学好C语言很难,其实是用好C语言太难。比如指针,其实不是指针本身比较难,而是指针用不好会导致系统内 存的破坏,破坏运行环境,所以会让程序员感觉指针很难。

\r\n

\r\n  鉴于它是C语言的超集,基本包括了C语言的所有特性(C99标准),得益于C语言的广泛应用,几乎适用于各个领域,各种操作系统平台,也是个人认 为最难的一种编程语言,但一旦精通之后再稍加学习其它语言很容易,基本无敌。其难在于功能强大与灵活,学好它的难度就是:C语言的难度+C++面向对象特 性+面向对象编程。C++是本人最喜欢的编程语言,其学习过程是漫长的,但一旦精通了C++,学习其它任何语言都非常快,它贯穿了从硬件到对象的整个过 程,学会了很容易让人看透编程语言的所有内幕。

\r\n

\r\n Windows上的快速开发语言,特别是对于界面比较多的应用,开发速度很快。其实C++ Builder也把扩展了一下C++也可用于快速开发,但自从有了C#以后,抢占了很大一部分RAD的市场,用的人也少了。

\r\n

\r\n 二者都可算是比C/C++更高一级的编程语言,一般不直接编译成机器码,需要通过虚拟机或类似虚拟机的运行时来运行,可以实现跨平台。他们与C /C++的不同之处就在于他们的编译过程分为两个阶段:编译和运行时编译,其实第一次的编译并不是直接生成机器码,而是生成一种便于编译成机器码的中间代 码,在实际运行的时候再通过所谓的运行时编译器(Just-In-Time Compiler)根据需要将中间代码编译成机器码并执行,实际上第一次编译更准确一点说是翻译。

\r\n

\r\n Java运行之广也是无人不知无人不晓,但其缺点在于对UI的支持不太好,无论在哪个平台做的界面都不太好,特别是在Windows上,用Java 实现界面的应用很少;C#是微软.Net战略的主要语言,也可以实现与Java一样广泛的应用,包括桌面应用和WEB应用,而且对UI的支持那是刚刚的。 虽然C#在Linux阵营也有Mono项目,虽然该项目Novell主持,但开源项目哪能像微软一样给力,实际应用非常少,所以C#的跨平台平不理想,仅 限于微软的Windows系列(包括移动应用)。

\r\n

\r\n   WEB开发前端脚本,特别是AJAX被作为一个专有名词提出来之后前台脚本已经不单单是进行一些简单的辅助,而成了WEB UI的主要实现形式,并且产生了很多流行的框架项目,如ExtJS、JQuery、Dojo等。这些语言与前面几种编程语言不同之处还在于其弱类型特性, 属于动态语言,设计思想与前面几种有些不同,虽然都支持面向对象但其实现方式稍有不同。学习它们会拓宽思路,帮助我们更深刻地理解编程语言。

\r\n

\r\n 脚本语言,特别是shell、VS Script属于轻量级的脚本语言,一般只用于批处理(虽然它们可以完成非常复杂的功能),尤其是shell(准确地说shell不是一种编程语言,由于 该语言是它专属,暂以代之);特别是shell应用范围最少,而后面的四种除了可用于批处理,还可以用于WEB编程,而且Ruby用于WEB开发已经非常 流行。

\r\n

\r\n 其中Python是本人比较喜欢的一种,它把程序的可读性要求提高了一个档次,把代码的缩进列入了语法范畴,这应该也是编程语言的趋势,以后可能将 注释的添加也列入注释范围,比如对每一个类、每个函数必须填写相应的注释,否则编译不通过,这样有助于更好地统一、执行一个工程编码的规范。

\r\n

\r\n 属于小众的编程语言,Lua有一个嵌入式脚本引擎,非常轻量级;Matlab的所谓M语言与Lua类似,它是Matlab专用的脚本语言。

\r\n

\r\n 不同的领域都有一些专门的脚本语言,真的希望这些语言能够是一种。

\r\n

\r\n 这些语言又是另一种类型的编程语言,这些语言通过标记来表示,特别是XML、HTML是一种静态的标记语言。而XSLT则可以有动态之意,属于 XML的一种派生语言,可以将XML文档转换成其它格式的文本文档这使得数据的展显非常方便,XML用于表示数据,通过不同的XSLT表现为不同的样式。

\r\n

\r\n 严格来讲CSS不应该算作一种编程语言,但它的确通过与HTML配合可以实现类似XSLT的效果,只是它暂时未从HTML中独立而已。

\r\n

\r\n 硬件描述语言,用于集成电路设计。它们也是编程语言,只是它编译后的产物不是类似CPU执行的指令那样的程序,而是对执行机构进行改造、重组的方案。

\r\n

\r\n  

\r\n

\r\n  

\r\n

\r\n 函数式编程语言,它们将电脑运算视为数学上的函数计算,并且避免状态以及可变数据,是另一种编程范型,又是一种编程思路。

\r\n

\r\n     编程语言远远不止这么多,也并不是一个程序员要精通这里所说的所有编程语言,个人认为每一类都应该熟悉一种,至少了解其编程思路,并达到可以读懂的程度, 而对于一些重要的编程语言,应该掌握,不仅要会读还要会写包括:C、C++、Java、C#、JavaScript等,但根据自己的工作领域不同可能的侧 重不同,视实际情况选择了解其它编程语言。

\r\n

\r\n 数据库必备,虽然标准是有,但不同的数据库还是有自己的一些特性,或者实现标准不完整,比如Cybase、DB2、Oracle、MySQL、SQLite、SQL Server等等,但只要掌握了标准的SQL,用其它语言的时候也只需要一个简单的手册而己。

\r\n

\r\n     《程序员修炼之道》里不也建议每年学习一门编程语言嘛,十类编程语言,十年寒窗,程序员的漫漫修炼之路。

\r\n
    \r\n
  1. \r\n
      \r\n
    • \r\n

      \r\n 汇编语言

      \r\n
    • \r\n
    \r\n
      \r\n
    • \r\n

      \r\n C

      \r\n
    • \r\n
    \r\n
      \r\n
    • \r\n

      \r\n C++、

      \r\n
    • \r\n
    \r\n
      \r\n
    • \r\n

      \r\n Visual Basic (.Net)、Delphi

      \r\n
    • \r\n
    \r\n
      \r\n
    • \r\n

      \r\n Java、C#

      \r\n
    • \r\n
    \r\n
      \r\n
    • \r\n

      \r\n Javascript、ActionScript

      \r\n
    • \r\n
    \r\n
      \r\n
    • \r\n

      \r\n shell、VB Script、Python、Perl、Ruby、PHP、TCL

      \r\n
    • \r\n
    \r\n
      \r\n
    • \r\n

      \r\n Lua、Matlab

      \r\n
    • \r\n
    \r\n
      \r\n
    • \r\n

      \r\n XML、HTML、XSLT、CSS

      \r\n
    • \r\n
    \r\n
      \r\n
    • \r\n

      \r\n Verilog、VHDL

      \r\n
    • \r\n
    \r\n
      \r\n
    • \r\n

      \r\n LISP、Haskell、Erlang

      \r\n
    • \r\n
    \r\n
      \r\n
    • \r\n

      \r\n SQL

      \r\n
    • \r\n
    \r\n
  2. \r\n
\r\n

\r\n 后:   

\r\n

\r\n   首先,感谢各位网友的讨论,可能标题为“掌握”不太准确,已经改为“熟悉”。

\r\n

\r\n    这里列的编程语言并不是每种都需要“精通”,那绝对是不可能的,而且我也还从来没有理解什么样的程度叫“精通”。根据每个人的所有领域不同使 用的主要语言也不同,工作用的语言肯定是需要“精通”的,除了工作用的语言,必须要掌握的语言有:C++(包括C)、Java或C#、SQL、 Javascript,需要熟悉的:perl或python、XML,其它的可以根据兴趣或应用领域选择。
\r\n   实际上,掌握了这些语言后已经从一个初级程序员变身为高级程序员,在学习过程中对设计模式、算法、操作系统、微机原理等知识的涉猎基本达到了一个初级 架构师的水平,如果自己的沟通能力、创新能力、管理能力等素质够硬还可以做到CTO的职位,这也是本人推荐的程序员的成长技术路线。

\r\n

\r\n   编程语言其实只是个工具,什么时候用哪个工具,如何用好每个工具非常重要,这里蕴含着很多知识、技能、思想。每学习一们编程语言,学习的不是语法,而是编程语言的精髓,解决问题的思维,重在思想。

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2860, '2011-c-dennis-ritchie-the-founder-of-the-death', '2011年C语言之父Dennis Ritchie辞世', '2012-10-15 08:56:49', '2019-03-25 21:29:22', '
\r\n

\r\n \"\"

\r\n

\r\n C语言发明人之一 Dennis Ritchie

\r\n

\r\n       Dennis Ritchie生于1941年9月9日。他发明了包括C语言在内的多种编程语言,并研发了Multics和Unix等操作系统。1983年,Dennis Ritchie获得图灵奖。2011年,Dennis Ritchie于当地时间10月12日去世,享年70岁。

\r\n

\r\n 著作

\r\n

\r\n 《C程序设计语言》

\r\n

\r\n 《Unix Programmer's Manual》

\r\n

\r\n 荣誉

\r\n

\r\n       从二十世纪七十年代起,他的工作得到了很多计算机组织的公认和表彰,如:美国计算机协会(ACM)授予的系统及语言杰出论文奖(1974);电气和电子工程 师协会(IEEE)的 Emmanuel Piore 奖(1982);贝尔实验室特别人员奖(1983);美国计算机协会(ACM)的图灵奖(1983);NEC公司的C&C基金奖(1989);电 气和电子工程师协会(IEEE)的优秀奖章(Hamming Medal)(1990),等等。

\r\n

\r\n 评价:

\r\n

\r\n       C 语言是使用最广泛的语言之一,可以说,C语言的诞生是现代程序语言革命的起点,是程序设计语言发展史中的一个里程碑。自C语言出现后,以C语言为根基的 C++、Java和C#等面向对象语言相继诞生,并在各自领域大获成功。但今天C语言依旧在系统编程、嵌入式编程等领域占据着统治地位。C语言,这种最有 效、最通用的编程语言,就是他开发的,而这还是他在做另一个项目时的副产品。Dennis Ritchie还和肯·汤普逊一起开发了Unix操作系统,因此,他还是名副其实的UNIX之父。

\r\n

\r\n       Dennis Ritchie先生的专业精神令人感动,近40年如一日,在他所从事的领域辛勤耕耘,而他的多项发明,包括C语言,Unix,也包括现在正在进行的 Plan9,无论哪一项,在软件发展史上都有着举足轻重的地位,和他的伟大成就形成对照的是他的行事,态度低调,他的表达,象他的软件一样,简洁生动而准 确。C++的成功,很大一部分也来自于C,是C语言的普及和深入,才有了后面的凤凰涅盘,从另一个角度,在同另一语言大师Pascal之父Niklaus Wirth交流时,C++的名字也是源自C语言的利器,Wirth先生不无惋惜地表示,后来他开发的语言可惜没叫Pascal2。

\r\n

\r\n 关于Dennis Ritchie

\r\n

\r\n       Dennis Ritchie,出生于美国纽约。著名的美国计算机科学家,对C语言和其他编程语言、Multics和Unix等操作系统的发展做出了巨大贡献。

\r\n

\r\n       Dennis Ritchie在哈佛大学学习物理学和应用数学毕业,1967年他进入贝尔实验室,他曾是朗讯技术公司系统软件研究部门的领导人(2007年退休)。 1983年他与肯·汤普逊一起获得了图灵奖。理由是他们“研究发展了通用的操作系统理论,尤其是实现了UNIX操作系统”。1999年两人为发展C语言和 Unix操作系统一起获得了美国国家技术奖章。

\r\n
\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2861, 'it-development-in-the-future-five-trends', 'IT未来发展五大趋势', '2012-10-15 08:50:24', '2019-03-25 21:29:22', '

\r\n  

\r\n
\r\n

\r\n \"\"

\r\n

\r\n       是否拥有一个关于创新可以影响商业发展的想法,是区分好的CIO与伟大的CIO的条件之一。所以,商业科技的下一步发展是什么?TechRepublic请教了五位科技领域内的专家,试图预测IT将来在企业内部或外部的发展情况。

\r\n

\r\n 1. 通过增强现实来提升体验

\r\n

\r\n       Economist Intelligence Unit全球技术研究主管Denis MaCauley一直致力于研究IT及增强现实的未来趋势,增强现实是备受关注的领域之一,主要是利用计算机生成数据来增强现实、真实世界环境的体验。

\r\n

\r\n       MaCauley表示增强的例子可能包括增加信息,比如向体育广播中添加事实和数字。“你拥有的一些东西是不能完全虚拟的,但可以利用计算机生成数据增强观赏体验。”他讲到。

\r\n

\r\n       企业和厂商希望在新领域进行投资,Juniper研究表明移动增强现实的收入在2015年将会达到15亿美元。MaCauley说,一些CIO相信增强现实能够在商业的特定领域出现可用的应用程序,如客服服务和员工培训。

\r\n

\r\n       “客户服务代表可以通过加大信息量覆盖多个屏幕,”MaCauley说,“游戏也是,在以往的组织活动中应用的并不多,但现在可以被当做工具去加强培训和进行头脑风暴活动。”

\r\n

\r\n 2. 移动科技越来越火

\r\n

\r\n       Gary Barr,零售巨头Wm Morrisons前IT总监。他表示,预测下一个发展领域是很难的,但他相信在近期的创新领域中仍然能有所收获,尤其是便携式设备及协作工具相关领域。

\r\n

\r\n       “在移动技术和社交媒体能够被称作是企业标准工具之前,还有很多时间发生别的事情,”他说。

\r\n

\r\n       “人们现在在工作场所内外都能够得益于一些令人难以置信的便携式技术,但CIO们不一定能够搞清这些协作工具是如何在工作场所背景下被使用的。”

\r\n

\r\n       Barr说,对于创新来说,需要有一段沉寂期,然后才可能被接受成为开展业务的新方式。他以千年之交的dot-com革命举例,认为那个时代的大品牌如Amazon和eBay经历了最好的十年,然后才成功。

\r\n

\r\n       “从大肆宣传的创新逐渐走向成熟,电子商务花了10年时间才成为强大的商业模式。”他指出,“同样,在这些创新真正能被作为优势采用之前,类似的事情也会发生在移动和社交科技领域。”

\r\n

\r\n 3. 创新与新技术一起发展

\r\n

\r\n       Toby Clarke,Abbey Protection集团保险专家组IT总监。他说,当你尝试思考企业IT的未来时,很难不把重点放在目前被夸大的技术发展领域。他指的是自身设备及云计算的增长潜力,并且他还列举了增强现实的例子。

\r\n

\r\n       但真正的创新,他说,将会与夸大的技术一起到来。“这是关于正在发生的一切的未来。”Clarke说到,他认为将会有越来越多的企业及客户数据会被组织继续收集起来。

\r\n

\r\n       “有如此多的数据,我们需要将它们集中起来。”Clarke说到。他指的是基于位置的服务增长及潜在的个性化服务水平,但这样的创新不是那么简单的。

\r\n

\r\n       “我目前努力尝试要看看这些数据存储库如何被链接起来。”他说,“现实情况是,一定有些东西是我的商业以及所有CIO可以在大数据方面可以一展身手的。但大量的创新工作仍然是必不可少的。”

\r\n

\r\n 4. 智能大数据

\r\n

\r\n       Francois Zimmerman,存储专家HDS的CTO,是另一位相信在现有科技趋势中在创新方面仍有一定操作空间的IT领导者。他相信在数据使用上仍有较大的发展空间。

\r\n

\r\n       “相对于市场炒作,这是现实中的实例,”他说,“商务智能,直到现在,一直都是时髦的新鲜事物,如大数据和厂商急于重新包装的现有工具如分析系统。”

\r\n

\r\n       他给CIO们的建议是不要想寻找一个单一的、现成的产品来解决他们所关注的问题。Zimmerman说,从现有情况分析来看,未来的举措将会面向更加具体的部门,以及帮助企业实时处理信息。

\r\n

\r\n       "首席信息官应该一切以案例为导向,应用反方向思维,从需要的业务成果追溯到技术的准备工作。"他说,“信息的未来将都会是有关业务流程的分析。”

\r\n

\r\n 5. 生物技术将迫使IT科技向前发展

\r\n

\r\n       Mark Bramwell,Wellcome Trust的IT部门负责人,他觉得技术发展方式能够意味着一些数字化趋势会出现出人意料的事情。

\r\n

\r\n       “IT的下一步发展是什么?这是价值64000美元的问题。”Bramwell说。但他认为,生物技术是一个正在发展并可能影响科技行业发展的领域。

\r\n

\r\n 顾问研究机构Ernst & Young报告指出,尽管2011年经济形势比较严峻,全球生物技术研究和发展指出仍然上升了9%。北美地区的投资尤为突出,去年在北美,有62%美国公共生物技术公司增加了他们的R&D支出。

\r\n

\r\n        基因组研究的进步使得医疗工作对现有的信息存储机制有巨大的需求。“IT需要促进医学研究发展。”Bramwell说。(责任编辑:魏兵)

\r\n

\r\n 原文来自:TechRepublic

\r\n
\r\n

\r\n  

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2862, 'first-under-myeclipse-struts2-project', 'MyEclipse下实现第一个struts2项目', '2012-10-15 07:30:44', '2019-03-25 21:29:22', '

\r\n       首先要准备好struts2开发包,你可以到官网下载http://struts.apache.org/。我是用的版本是struts-2.3.4.1。接下来就可以开始了:

\r\n

\r\n 1.建立项目。打开MyEclipse,建立一个Web Project。
\r\n 2.添加jar包。在WebRoot->WEB-INFO->lib目录下添加struts2运行必须的jar包,共11个。分别是:asm-3.3.jarasm-commons-3.3.jarasm-tree-3.3.jarcommons-fileupload-1.2.2.jarcommons-io-2.0.1.jarcommons-lang3-3.1.jarfreemarker-2.3.19.jar、javassist-3.11.0.GA.jarognl-3.0.5.jarstruts2-core-2.3.4.1.jar、xwork-core-2.3.4.1.jar。如果你不确定要加那些jar包,可以到开发包的app中struts-blank里面找。也可以

\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n \"\"\r\n 点此下载struts运行必备jar包
\r\n

\r\n
\r\n \"\"
\r\n 此时,在Web App Libiaries里面就可以看到你引用的jar包了。
\r\n \"\"
\r\n 然后在WebRoot下新建一个页面login.jsp,内容如下:

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>\r\n<%\r\nString path = request.getContextPath();\r\nString basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";\r\n%>\r\n\r\n<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">\r\n<html>\r\n  <head>\r\n    <base href="<%=basePath%>">\r\n\r\n    <title>My JSP 'login.jsp' starting page</title>\r\n\r\n	<meta http-equiv="pragma" content="no-cache">\r\n	<meta http-equiv="cache-control" content="no-cache">\r\n	<meta http-equiv="expires" content="0">\r\n	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">\r\n	<meta http-equiv="description" content="This is my page">\r\n	<!--\r\n	<link rel="stylesheet" type="text/css" href="styles.css">\r\n	-->\r\n\r\n  </head>\r\n\r\n  <body>\r\n   username:<input type="text" name="username"><br>\r\n   password:<input type="password" name="userpwd"><br>\r\n   <input type="submit" value="submit">\r\n  </body>\r\n\r\n</html>\r\n
\r\n
\r\n
\r\n接下来,修改web.xml。如下
\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n<?xml version="1.0" encoding="UTF-8"?>\r\n<web-app id="WebApp_9" version="2.4"\r\nxmlns="http://java.sun.com/xml/ns/j2ee"\r\nxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r\nxsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">\r\n\r\n<filter>\r\n<filter-name>struts2</filter-name>\r\n<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>\r\n</filter>\r\n\r\n\r\n<filter-mapping>\r\n<filter-name>struts2</filter-name>\r\n<url-pattern>/*</url-pattern>\r\n</filter-mapping>\r\n\r\n</web-app>\r\n
\r\n
\r\n
\r\n然后,在src目录下建立一个struts.xml文件,内容如下:
\r\n然后在src目录下建立一个package名为com.xinvalue。
\r\n在此package下建立一个class命名LoginAction.java。
\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\npackage com.xinvalue;\r\n\r\npublic class LoginAction\r\n{\r\n	private String username;\r\n	private String password;\r\n\r\n	public String getUsername()\r\n	{\r\n		return username;\r\n	}\r\n\r\n	public void setUsername(String username)\r\n	{\r\n		this.username = username;\r\n	}\r\n\r\n	public String getPassword()\r\n	{\r\n		return password;\r\n	}\r\n\r\n	public void setPassword(String password)\r\n	{\r\n		this.password = password;\r\n	}\r\n\r\n}\r\n
\r\n
\r\n然后建立一个result.jsp页面。
\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n共和国
\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2863, 'vmware-with-redhat-this-disc-cannot-be-mounted', 'vmware装redhat该光盘无法被挂载', '2012-10-10 07:20:03', '2019-03-25 21:29:22', '

\r\n       最近为在学linux,于是前天在vmware8装redhat 提示该光盘无法被挂载,还以为是光盘错误,换了N个盘,又装了很多次,最后观察到,换了盘之后点确定,里面就提示该光盘无法被挂载,根本就没有读光盘。 郁闷......

\r\n

\r\n \"vmware装redhat该光盘无法被挂载       

\r\n

\r\n 后来才发现,VMware换了光盘之后(或安装过程弹出换CD后),竟然默认断开光盘连接,也就是说光驱处于Disconnect的状态。

\r\n

\r\n \"vmware装redhat该光盘无法被挂载

\r\n

\r\n 打开配置,CD/DVD里面的驱动器状态connected的√没打上,当然系统也就无法挂载光驱了。
\r\n \"vmware装redhat该光盘无法被挂载            

\r\n

\r\n 点击虚拟机右下角的光盘图标,settings更换光盘后,再选择connect。
\r\n 一切OK。

\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2864, 'how-to-block-js-errors', '如何屏蔽JS错误', '2012-10-07 08:44:54', '2019-03-25 21:29:22', '

\r\n 在所有的JS加载的最前面加上如下代码:

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n<script>window.onerror=function(){return true;};</script>
\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2865, 'asp-net-completely-disabling-viewstate', 'ASP.NET彻底禁用ViewState', '2012-10-06 14:12:32', '2019-03-25 21:29:22', '

\r\n       ViewState禁用之前:
\r\n \"\"
\r\n       后面太多就不截图了。
\r\n       我们可以对每个控件分别禁用,即把控件的EnableViewState属性设为false,如果对页面,可以在Page中设置,将整个页面的VewState禁用掉,但是这种禁用并不彻底,hidden域仍然有值:

\r\n
\r\n \"\"      
\r\n
\r\n    \"\"
\r\n
\r\n \"\"

\r\n      要彻底禁用ViewState,需要重写两个函数:
\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n    protected override void SavePageStateToPersistenceMedium(object viewState)\r\n    {\r\n    // do nothing\r\n    }\r\n\r\n    protected override object LoadPageStateFromPersistenceMedium()\r\n    {\r\n    return null;\r\n    }
\r\n
\r\n

\r\n       这样ViewState就彻底禁用了,查看源码。发现hidden域的值已经为空了:

\r\n

\r\n \"\"

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2866, 'jquery-gets-the-selectdropdownlistcheckbox-value-of-the-drop-down-list-box', 'Jquery获取select,dropdownlist,checkbox下拉列表框的值', '2012-09-27 18:18:49', '2019-03-25 21:29:22', '

\r\n jQuery获取Select选择的Text和Value: 
\r\n 语法解释: 
\r\n 1. $("#select_id").change(function(){//code...});   //为Select添加事件,当选择其中一项时触发 
\r\n 2. var checkText=$("#select_id").find("option:selected").text();  //获取Select选择的Text 
\r\n 3. var checkValue=$("#select_id").val();  //获取Select选择的Value 
\r\n 4. var checkIndex=$("#select_id ").get(0).selectedIndex;  //获取Select选择的索引值 
\r\n 5. var maxIndex=$("#select_id option:last").attr("index");  //获取Select最大的索引值  
\r\n jQuery设置Select选择的Text和Value: 
\r\n 语法解释: 
\r\n 1. $("#select_id ").get(0).selectedIndex=1;  //设置Select索引值为1的项选中 
\r\n 2. $("#select_id ").val(4);   //设置Select的Value值为4的项选中 
\r\n 3. $("#select_id option[text='jQuery']").attr("selected", true);   //设置Select的Text值为jQuery的项选中 
\r\n  
\r\n jQuery添加/删除Select的Option项: 
\r\n 语法解释: 
\r\n 1. $("#select_id").append("<option value='Value'>Text</option>");  //为Select追加一个Option(下拉项) 
\r\n 2. $("#select_id").prepend("<option value='0'>请选择</option>");  //为Select插入一个Option(第一个位置) 
\r\n 3. $("#select_id option:last").remove();  //删除Select中索引值最大Option(最后一个) 
\r\n 4. $("#select_id option[index='0']").remove();  //删除Select中索引值为0的Option(第一个) 
\r\n 5. $("#select_id option[value='3']").remove();  //删除Select中Value='3'的Option 
\r\n 5. $("#select_id option[text='4']").remove();  //删除Select中Text='4'的Option 
\r\n http://www.cnblogs.com/SAL2928/archive/2008/10/28/1321285.html 
\r\n  
\r\n jquery radio取值,checkbox取值,select取值,radio选中,checkbox选中,select选中,及其相关  
\r\n 获取一组radio被选中项的值  
\r\n var item = $('input[@name=items][@checked]').val();  
\r\n 获取select被选中项的文本  
\r\n var item = $("select[@name=items] option[@selected]").text();  
\r\n select下拉框的第二个元素为当前选中值  
\r\n $('#select_id')[0].selectedIndex = 1;  
\r\n radio单选组的第二个元素为当前选中值  
\r\n $('input[@name=items]').get(1).checked = true;  
\r\n  
\r\n 获取值:  
\r\n  
\r\n 文本框,文本区域:$("#txt").attr("value");  
\r\n 多选框checkbox:$("#checkbox_id").attr("value");  
\r\n 单选组radio:   $("input[@type=radio][@checked]").val();  
\r\n 下拉框select: $('#sel').val();  
\r\n  
\r\n 控制表单元素:  
\r\n 文本框,文本区域:$("#txt").attr("value",'');//清空内容  
\r\n                  $("#txt").attr("value",'11');//填充内容  
\r\n  
\r\n 多选框checkbox: $("#chk1").attr("checked",'');//不打勾  
\r\n                  $("#chk2").attr("checked",true);//打勾  
\r\n                  if($("#chk1").attr('checked')==undefined) //判断是否已经打勾  
\r\n  
\r\n 单选组radio:    $("input[@type=radio]").attr("checked",'2');//设置value=2的项目为当前选中项  
\r\n 下拉框select:   $("#sel").attr("value",'-sel3');//设置value=-sel3的项目为当前选中项  
\r\n                 $("<option value='1'>1111</option><option value='2'>2222</option>").appendTo("#sel")//添加下拉框的option  
\r\n                 $("#sel").empty();//清空下拉框 
\r\n  
\r\n ---------------------------------------------------------------------------------------------------- 
\r\n  
\r\n  
\r\n //遍历option和添加、移除option 
\r\n function changeShipMethod(shipping){ 
\r\n var len = $("select[@name=ISHIPTYPE] option").length 
\r\n if(shipping.value != "CA"){ 
\r\n $("select[@name=ISHIPTYPE] option").each(function(){ 
\r\n if($(this).val() == 111){ 
\r\n $(this).remove(); 
\r\n } 
\r\n }); 
\r\n }else{ 
\r\n $("<option value='111'>UPS Ground</option>").appendTo($("select[@name=ISHIPTYPE]")); 
\r\n } 
\r\n } 
\r\n  
\r\n  

\r\n #p#副标题#e#
\r\n //取得下拉選單的選取值 
\r\n  
\r\n $(#testSelect option:selected').text(); 
\r\n 或$("#testSelect").find('option:selected').text(); 
\r\n 或$("#testSelect").val(); 
\r\n ////////////////////////////////////////////////////////////////// 
\r\n 记性不好的可以收藏下: 
\r\n 1,下拉框: 
\r\n  
\r\n var cc1 = $(".formc select[@name='country'] option[@selected]").text(); //得到下拉菜单的选中项的文本(注意中间有空格) 
\r\n var cc2 = $('.formc select[@name="country"]').val(); //得到下拉菜单的选中项的值 
\r\n var cc3 = $('.formc select[@name="country"]').attr("id"); //得到下拉菜单的选中项的ID属性值 
\r\n $("#select").empty();//清空下拉框//$("#select").html(''); 
\r\n $("<option value='1'>1111</option>").appendTo("#select")//添加下拉框的option 
\r\n  
\r\n 稍微解释一下: 
\r\n 1.select[@name='country'] option[@selected] 表示具有name 属性, 
\r\n 并且该属性值为'country' 的select元素 里面的具有selected 属性的option 元素; 
\r\n 可以看出有@开头的就表示后面跟的是属性。 
\r\n  
\r\n 2,单选框: 
\r\n $("input[@type=radio][@checked]").val(); //得到单选框的选中项的值(注意中间没有空格) 
\r\n $("input[@type=radio][@value=2]").attr("checked",'checked'); //设置单选框value=2的为选中状态.(注意中间没有空格) 
\r\n  
\r\n 3,复选框: 
\r\n $("input[@type=checkbox][@checked]").val(); //得到复选框的选中的第一项的值 
\r\n $("input[@type=checkbox][@checked]").each(function(){ //由于复选框一般选中的是多个,所以可以循环输出 
\r\n alert($(this).val()); 
\r\n }); 
\r\n  
\r\n $("#chk1").attr("checked",'');//不打勾 
\r\n $("#chk2").attr("checked",true);//打勾 
\r\n if($("#chk1").attr('checked')==undefined){} //判断是否已经打勾 
\r\n  
\r\n  
\r\n 当然jquery的选择器是强大的. 还有很多方法. 
\r\n  
\r\n <script src="jquery-1.2.1.js" type="text/javascript"></script> 
\r\n <script language="javascript" type="text/javascript"> 
\r\n $(document).ready(function(){ 
\r\n $("#selectTest").change(function() 
\r\n { 
\r\n //alert("Hello"); 
\r\n //alert($("#selectTest").attr("name")); 
\r\n //$("a").attr("href","xx.html"); 
\r\n //window.location.href="xx.html"; 
\r\n //alert($("#selectTest").val()); 
\r\n alert($("#selectTest option[@selected]").text()); 
\r\n $("#selectTest").attr("value", "2"); 
\r\n  
\r\n }); 
\r\n }); 
\r\n </script> 
\r\n  
\r\n  
\r\n <a href="#">aaass</a> 
\r\n  
\r\n <!--下拉框--> 
\r\n <select id="selectTest" name="selectTest"> 
\r\n <option value="1">11</option> 
\r\n <option value="2">22</option> 
\r\n <option value="3">33</option> 
\r\n <option value="4">44</option> 
\r\n <option value="5">55</option> 
\r\n <option value="6">66</option> 
\r\n </select> 
\r\n jquery radio取值,checkbox取值,select取值,radio选中,checkbox选中,select选中,及其相关获取一组radio被选中项的值 
\r\n var item = $('input[@name=items][@checked]').val(); 
\r\n 获取select被选中项的文本 
\r\n var item = $("select[@name=items] option[@selected]").text(); 
\r\n select下拉框的第二个元素为当前选中值 
\r\n $('#select_id')[0].selectedIndex = 1; 
\r\n radio单选组的第二个元素为当前选中值 
\r\n $('input[@name=items]').get(1).checked = true; 

\r\n
\r\n #p#副标题#e#
\r\n 获取值: 
\r\n 文本框,文本区域:$("#txt").attr("value"); 
\r\n 多选框checkbox:$("#checkbox_id").attr("value"); 
\r\n 单选组radio: $("input[@type=radio][@checked]").val(); 
\r\n 下拉框select: $('#sel').val(); 
\r\n 控制表单元素: 
\r\n 文本框,文本区域:$("#txt").attr("value",'');//清空内容 
\r\n $("#txt").attr("value",'11');//填充内容 
\r\n 多选框checkbox: $("#chk1").attr("checked",'');//不打勾 
\r\n $("#chk2").attr("checked",true);//打勾 
\r\n if($("#chk1").attr('checked')==undefined) //判断是否已经打勾 
\r\n 单选组radio: $("input[@type=radio]").attr("checked",'2');//设置value=2的项目为当前选中项 
\r\n 下拉框select: $("#sel").attr("value",'-sel3');//设置value=-sel3的项目为当前选中项 
\r\n $("<optionvalueoptionvalue='1'>1111</option>< optionvalueoptionvalue='2'>2222</option>").appendTo("#sel")//添加 下拉框的option 
\r\n $("#sel").empty();//清空下拉框 
\r\n  
\r\n 获取一组radio被选中项的值 
\r\n var item = $('input[@name=items][@checked]').val(); 
\r\n 获取select被选中项的文本 
\r\n var item = $("select[@name=items] option[@selected]").text(); 
\r\n select下拉框的第二个元素为当前选中值 
\r\n $('#select_id')[0].selectedIndex = 1; 
\r\n radio单选组的第二个元素为当前选中值 
\r\n $('input[@name=items]').get(1).checked = true; 
\r\n 获取值: 
\r\n 文本框,文本区域:$("#txt").attr("value"); 
\r\n 多选框checkbox:$("#checkbox_id").attr("value"); 
\r\n 单选组radio: $("input[@type=radio][@checked]").val(); 
\r\n 下拉框select: $('#sel').val(); 
\r\n 控制表单元素: 
\r\n 文本框,文本区域:$("#txt").attr("value",'');//清空内容 
\r\n $("#txt").attr("value",'11');//填充内容 
\r\n 多选框checkbox: $("#chk1").attr("checked",'');//不打勾 
\r\n $("#chk2").attr("checked",true);//打勾 
\r\n if($("#chk1").attr('checked')==undefined) //判断是否已经打勾 
\r\n 单选组radio: $("input[@type=radio]").attr("checked",'2');//设置value=2的项目为当前选中项 
\r\n 下拉框select: $("#sel").attr("value",'-sel3');//设置value=-sel3的项目为当前选中项 
\r\n $("<option value='1'>1111</option><option value='2'>2222</option>").appendTo("#sel")//添加下拉框的option 
\r\n $("#sel").empty();//清空下拉框

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2867, 'value-of-javascript-front-asp-net-server-controls-in-the-background', 'JavaScript前台取后台ASP.NET服务器控件的值', '2012-09-26 07:25:55', '2019-03-25 21:29:22', '

\r\n JavaScript前台取后台ASP.NET服务器控件的值
\r\n
\r\n document.getElementById( "<%=服务器控件ID名.ClientID%> ")
\r\n
\r\n 示例:document.getElementById( " <%=TextBox1.ClientID %> ")

\r\n后台代码:\r\n

\r\n \"\"

\r\n前台生成的html页面:\r\n

\r\n \"\"

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2868, 'written-in-assembly-language-environment-set-up-and-helloworld', '汇编语言环境的搭建及HelloWorld的编写', '2012-09-18 07:03:56', '2019-03-25 21:29:22', '     准备
\r\n    
masm32下载链接:http://www.masm32.com/masmdl.htm 那个下面有中文就是中国程序员下载。
\r\n

\r\n 代码

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n.386\r\n.model flat, stdcall\r\noption casemap :none\r\ninclude masm32includewindows.inc\r\ninclude masm32includekernel32.inc\r\ninclude masm32includeuser32.inc\r\nincludelib masm32libkernel32.lib\r\nincludelib masm32libuser32.lib\r\n.data\r\nHelloWorld db "Hello World!", 0\r\n.code\r\nstart:\r\ninvoke MessageBoxA, NULL, addr HelloWorld, addr HelloWorld, MB_OK\r\ninvoke ExitProcess, 0\r\nend start
\r\n
\r\n
\r\n

\r\n 保存代码,我保存为HelloWorld.asm

\r\n

\r\n 然后file->Cmd prompt

\r\n

\r\n 输入 ml /c /coff HelloWorld.asm

\r\n

\r\n 这是正常情况下可以看到

\r\n

\r\n       \"自我折磨之汇编--Helloworld(masm11forwin7)

\r\n

\r\n  接着输入link /SUBSYSTEM:WINDOWS HelloWorld.obj

\r\n

\r\n        \"自我折磨之汇编--Helloworld(masm11forwin7)

\r\n

\r\n  那么这个时候你已经能在你的文件夹里面看到一个exe的文件了基本上helloworld已经OK了。

\r\n

\r\n \"\"

\r\n

\r\n       需要注意的问题
\r\n       首先是要了解的是编译和链接之间概念是不同的。我在配置中间就遇到了这个问题,ml的时候是需要加参数的,这些参数与这个知识点相关,链接的时候也是一 样
。  

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2869, 'analysis-of-the-linux-process-scheduler', 'Linux进程调度浅析', '2012-09-17 06:01:07', '2019-03-25 21:29:22', '

\r\n 一:Linux进程的四大要素
\r\n 1:一段供进程执行的程序,该程序可以被多个进程执行。
\r\n 2:独立的内核堆栈。
\r\n 3:进程控制快(task_struct:有了这个数据结构,进程才能成为内核调度的一个基本单位接受内核的调度。同时,这个结构还记录着进程所占用的各项资源。
\r\n 4:独立的存储空间:即拥有专有的用户空间,除了前面的内核空间还有用户空间。
\r\n 线程:只有前三条,没有第四条。
\r\n 内核线程:完全没有用户空间。
\r\n 用户线程:共享用户空间。
\r\n
\r\n 二:Linux进程分类:
\r\n 1:交互式进程:这些进程经常和用户发生交互,所以花费一些时间等待用户的操作。当有输入时,进程必须很快的激活。通常,要求延迟在50-150毫秒。典型的交互式进程有:控制台命令,文本编辑器,图形应用程序。
\r\n 2:批处理进程(Batch Process):不需要用户交互,一般在后台运行。所以不需要非常快的反应,他们经常被调度期限制。典型的批处理进程:编译器,数据库搜索引擎和科学计算。
\r\n 3:实时进程:对调度有非常严格的要求,这种类型的进程不能被低优先级进程阻塞,并且在很短的时间内做出反应。典型的实时进程:音视频应用程序,机器人控制等。
\r\n 批处理进程可能与I/O或者CPU有关,但是实时进程完全通过Linux的调度算法识别。
\r\n 其实交互式进程和批处理进程很难区别。
\r\n 三:Linux进程优先级
\r\n 1:静态优先级(priority): 被称为“静态”是因为它不随时间而改变,只能由用户进行修改。它指明了在被迫和其它进程竞争CPU之前该进程所应该被允许的时间片的最大值(20)。
\r\n
\r\n 每 个普通进程都一个静态优先级,内核为其分配的优先级数为:100(高优先级)-139(低优先级)。数值越大,优先级越低。新创建的进程一般继承父进程的 优先级,但是用户可以通过给nice()函数传递“nice value“或者setpriority()改变优先级。
\r\n
\r\n 2: 动态优先级(counter): counter 即系统为每个进程运行而分配的时间片,Linux 兼用它来表示进程的动态优先级。只要进程拥有CPU,它就随着时间不断减小;当它为0 时,标记进程重新调度。它指明了在当前时间片中所剩余的时间量(最初为20)
\r\n
\r\n 事实上,在进程在调度的时候,调度器只察看动态优先级,其值为100-139。通过下面的公式可以根据静态优先计算出相应的动态优先级。
\r\n Dynamicy priority = max (100, min (static priority - bonus + 5, 139))   
\r\n
\r\n Bonus:0-10,比5小,降低动态优先级,反之,可以提高动态优先级。Bonus和进程的平均睡眠时间有关。
\r\n
\r\n 3: 实时优先级(rt_priority):值为1000。Linux把实时优先级与counter值相加作为实时进程的优先权值。较高权值的进程总是优先于较低权值的进程,如果一个进程不是实时进程,
\r\n 其优先权就远小于1000,所以实时进程总是优先。
\r\n
\r\n 4:Base time quantum:是由静态优先级决定,当进程耗尽当前Base time quantum,kernel会重新分配一个Base time quantum给它。静态优先级和Base time quantum的关系为:
\r\n (1)        当静态优先级小于120
\r\n       Base time quantum(in millisecond)= (140 – static priority) * 20
\r\n (2)        当静态优先级大于等于120
\r\n       Base time quantum(in millisecond)= (140 – static priority) * 5
\r\n
\r\n 四:Linux 进程的调度算法
\r\n 1. 时间片轮转调度算法(round-robin):SCHED_RR,用于实时进程。系统使每个进程依次地按时间片轮流执行的方式。
\r\n 2. 优先权调度算法:SCHED_NORMAL,用于非实时进程。系统选择运行队列中优先级最高的进程运行。Linux 采用抢占式的优级算法,即系统中当前运行的进程永远是可运行进程中优先权最高的那个。
\r\n 3. FIFO(先进先出) 调度算法:SCHED_FIFO,实时进程按调度策略分为两种。采用FIFO的实时进程必须是运行时间较短的进程,因为这种进程一旦获得CPU 就只有等到它运行完或因等待资源主动放弃CPU时其它进程才能获得运行机会。
\r\n
\r\n 五:Linux 进程的调度时机
\r\n 1.进程状态转换时: 如进程终止,睡眠等;
\r\n 2.可运行队列中增加新的进程时;
\r\n 3.当前进程的时间片耗尽时;
\r\n 4.进程从系统调用返回到用户态时;
\r\n 5.内核处理完中断后,进程返回到用户态;
\r\n
\r\n 六:进程队列:
\r\n 对队列都有初始化、添加、删除等功能。
\r\n 1:运行队列:Linux系统为处于就绪态的进程的队列,只有在这个队列中的进程才有机会获得CPU。
\r\n 2:等待队列:,Linux系统也为处于睡眠态的进程组建了一个队列。

\r\n
\r\n #p#副标题#e#
\r\n 七:调度使用的数据结构
\r\n 1:runqueue
\r\n Runqueu是调度器中非常重要的一个数据结构,每个CPU都有自己的runqueue。
\r\n
\r\n
\r\n
\r\n requeue
\r\n Type        Name        Description
\r\n spinlock_t        lock        保护进程列表的自旋锁
\r\n unsigned long        nr_running        runqueue 列表中可运行进程数。
\r\n unsigned long        cpu_load        基于runqueue平均进程数的CPU 加载因子
\r\n unsigned long        nr_switches        CPU运行的进程切换次数
\r\n unsigned long        nr_uninterruptible        曾经在runqueue但是现在处于 TASK_UNINTERRUPTIBLE 状态的进程数
\r\n unsigned long        expired_timestamp        老进程已经插入expired列表中的时间
\r\n unsigned long long        timestamp_last_tick        最后一次时钟中断的Timestamp值
\r\n task_t *        curr        当前运行进程描述符的指针
\r\n task_t *        idle        进程描述符指针,指向当前CPU的swappe进程
\r\n struct mm_struct *        prev_mm        在进程却换工程中,保存正被替换的进程的地址空间
\r\n prio_array_t *        active        指向激活进程列表(arrays 中的一个)
\r\n prio_array_t *        expired        指向expired进程列表(arrays 中的一个)
\r\n prio_array_t [2]        arrays        激活和expired进程的2维数组,每个prio_array_t代表一组可运行进程,140个双向列表,静态bitmap以及这组进程的counter.
\r\n int        best_expired_prio        在expired进程中最低的静态优先级
\r\n atomic_t        nr_iowait        曾经在runqueue但是现在正在等待I/O操作完成的进程数
\r\n struct sched_domain *        sd        指向当前CPU的基本调度域
\r\n int        active_balance        标志一些进程将被从一个requeue转移到其他requeue队列
\r\n int        push_cpu        没有使用
\r\n task_t *        migration_thread        内核转移线程的进程描述符
\r\n struct list_head        migration_queue        将被从requeue中转移的进程列表
\r\n
\r\n 九:调度使用的重要函数
\r\n 调度需要一系列函数配合完成调度这一功能,其中最重要的如下:
\r\n 调度重要函数
\r\n scheduler_tick        更新当前进程的time_slice。该函数有两种调用途径:
\r\n 1:timer,调用频率为HZ,并且在关中断的情况下调用。
\r\n 2:fork代码,当改变父进程的timeslice时。
\r\n try_to_wake_up        唤醒sleep进程。当进程不在可运行队列时,将其放在可运行队列。
\r\n recalc_task_prio        更新进程的动态优先级
\r\n schedule        选择一个进程运行
\r\n load_balance        保持多系统下runqueue平衡。检查当前CPU,保证一个域中runqueue平衡。
\r\n
\r\n 1:在进程却换前,scheduler做的事情
\r\n Schedule所作的事情是用某一个进程替换当前进程。
\r\n (1)        关闭内核抢占,初始化一些局部变量。
\r\n need_resched:
\r\n
\r\n preempt_disable( );
\r\n prev = current;
\r\n rq = this_rq( );
\r\n 当前进程current被保存在prev,和当前CPU相关的runqueue的地址保存在rq中。
\r\n (2)        检查prev没有持有big kernel lock.
\r\n if (prev->lock_depth >= 0)
\r\n up(&kernel_sem);
\r\n Schedule没有改变lock_depth的值,在prev唤醒自己执行的情况下,如果lock_depth的值不是负的,prev需要重新获取kernel_flag自旋锁。所以大内核锁在进程却换过程中是自动释放的和自动获取的。
\r\n (3)        调用sched_clock( ),读取TSC,并且将TSC转换成纳秒,得到的timestamp保存在now中,然后Schedule计算prev使用的时间片。
\r\n now = sched_clock( );
\r\n run_time = now - prev->timestamp;
\r\n if (run_time > 1000000000)
\r\n     run_time = 1000000000;
\r\n (4)        在察看可运行进程的时候,schedule必须关闭当前CPU中断,并且获取自旋锁保护runqueue.
\r\n spin_lock_irq(&rq->lock);
\r\n (5)        为了识别当前进程是否已经终止,schedule检查PF_DEAD标志。
\r\n if (prev->flags & PF_DEAD)
\r\n     prev->state = EXIT_DEAD;
\r\n (6)        Schedule检查prev的状态,如果它是不可运行的,并且在内核态没有被抢占,那么从runqueue删除它。但是,如果prev有非阻塞等待信号 并且它的状态是TASK_INTERRUPTBLE,设置其状态为TASK_RUNNING,并且把它留在runqueue中。该动作和分配CPU给 prev不一样,只是给prev一个重新选择执行的机会。
\r\n if (prev->state != TASK_RUNNING &&
\r\n     !(preempt_count() & PREEMPT_ACTIVE)) {
\r\n     if (prev->state == TASK_INTERRUPTIBLE && signal_pending(prev))
\r\n         prev->state = TASK_RUNNING;
\r\n     else {
\r\n         if (prev->state == TASK_UNINTERRUPTIBLE)
\r\n             rq->nr_uninterruptible++;
\r\n         deactivate_task(prev, rq);
\r\n     }
\r\n }
\r\n deactivate_task( )是从runqueue移除进程:
\r\n rq->nr_running--;
\r\n dequeue_task(p, p->array);
\r\n p->array = NULL;

\r\n
\r\n #p#副标题#e#
\r\n (7)        检查runqueue中进程数,
\r\n A: 如果有多个可运行进程,调用dependent_sleeper( )函数。一般情况下,该函数立即返回0,但是如果内核支持超线程技术,该函数检查将被运行的进程是否有比已经运行在同一个物理CPU上一个逻辑CPU上的 兄弟进程的优先级低。如果是,schedule拒绝选择低优先级进程,而是执行swapper进程。
\r\n if (rq->nr_running) {
\r\n     if (dependent_sleeper(smp_processor_id( ), rq)) {
\r\n         next = rq->idle;
\r\n         goto switch_tasks;
\r\n     }
\r\n }
\r\n B:如果没有可运行进程,调用idle_balance( ),从其他runqueue队列中移动一些进程到当前runqueue,idle_balance( )和load_balance( )相似。
\r\n if (!rq->nr_running) {
\r\n     idle_balance(smp_processor_id( ), rq);
\r\n     if (!rq->nr_running) {
\r\n         next = rq->idle;
\r\n         rq->expired_timestamp = 0;
\r\n         wake_sleeping_dependent(smp_processor_id( ), rq);
\r\n         if (!rq->nr_running)
\r\n             goto switch_tasks;
\r\n     }
\r\n }
\r\n 如果idle_balance( )移动一些进程到当前runqueue失败,schedule( )调用wake_sleeping_dependent( )重新唤醒空闲CPU的可运行进程。
\r\n
\r\n 假 设schedule( )已经决定runqueue中有可运行进程,那么它必须检查可运行进程中至少有一个进程是激活的。如果没有,交换runqueue中active 和expired域的内容,所有expired进程变成激活的,空数组准备接受以后expire的进程。
\r\n if (unlikely(!array->nr_active)) {
\r\n                 /*
\r\n                  * Switch the active and expired arrays.
\r\n                  */
\r\n                 schedstat_inc(rq, sched_switch);
\r\n                 rq->active = rq->expired;
\r\n                 rq->expired = array;
\r\n                 array = rq->active;
\r\n                 rq->expired_timestamp = 0;
\r\n                 rq->best_expired_prio = MAX_PRIO;
\r\n         }
\r\n (8)        查找在active prio_array_t数组中的可运行进程。Schedule在active数组的位掩码中查找第一个非0位。当优先级列表不为0的时候,相应的位掩码 北设置,所以第一个不为0的位标示一个有最合适进程运行的列表。然后列表中第一个进程描述符被获取。
\r\n idx = sched_find_first_bit(array->bitmap);
\r\n         queue = array->queue + idx;
\r\n         next = list_entry(queue->next, task_t, run_list);
\r\n     现在next指向将替换prev的进程描述符。
\r\n (9)        检查next->activated,它标示唤醒进程的状态。
\r\n (10)        如果next是一个普通进程,并且是从TASK_INTERRUPTIBLE 或者TASK_STOPPED状态唤醒。Scheduler在进程的平均睡眠时间上加从进程加入到runqueue开始的等待时间。
\r\n
\r\n if (!rt_task(next) && next->activated > 0) {
\r\n                 unsigned long long delta = now - next->timestamp;
\r\n                 if (unlikely((long long)(now - next->timestamp) < 0))
\r\n                         delta = 0;
\r\n
\r\n                 if (next->activated == 1)
\r\n                         delta = delta * (ON_RUNQUEUE_WEIGHT * 128 / 100) / 128;
\r\n
\r\n                 array = next->array;
\r\n                 new_prio = recalc_task_prio(next, next->timestamp + delta);
\r\n
\r\n                 if (unlikely(next->prio != new_prio)) {
\r\n                         dequeue_task(next, array);
\r\n                         next->prio = new_prio;
\r\n                         enqueue_task(next, array);
\r\n                 } else
\r\n                         requeue_task(next, array);
\r\n         }
\r\n         next->activated = 0;
\r\n
\r\n
\r\n Scheduler区分被中断或者被延迟函数唤醒的进程与被系统调用服务程序或者内核线程唤醒的进程。前者,Scheduler加整个runqueue等待时间,后者只加一部分时间。
\r\n 2:进程却换时,Scheduler做的事情:
\r\n 现在,Scheduler已经确定要运行的进程。
\r\n (1)        访问next的thread_info,它的地址保存在next进程描述符的顶部。
\r\n switch_tasks:
\r\n         if (next == rq->idle)
\r\n                 schedstat_inc(rq, sched_goidle);
\r\n         prefetch(next)
\r\n (2)        在替换prev前,执行一些管理工作
\r\n clear_tsk_need_resched(prev);
\r\n         rcu_qsctr_inc(task_cpu(prev));
\r\n clear_tsk_need_resched清除prev的TIF_NEED_RESCHED,该动作只发生在Scheduler是被间接调用的情况。
\r\n (3)        减少prev的平均睡眠时间到进程使用的cpu时间片。
\r\n         prev->sleep_avg -= run_time;
\r\n         if ((long)prev->sleep_avg <= 0)
\r\n                 prev->sleep_avg = 0;
\r\n         prev->timestamp = prev->last_ran = now;

\r\n
\r\n #p#副标题#e#
\r\n (4)        检查是否prev和next是同一个进程,如果为真,放弃进程却换,否则,执行(5)
\r\n    if (prev == next) {
\r\n     spin_unlock_irq(&rq->lock);
\r\n     goto finish_schedule;
\r\n }
\r\n
\r\n (5)        真正的进程却换
\r\n                 next->timestamp = now;
\r\n                 rq->nr_switches++;
\r\n                 rq->curr = next;
\r\n                 ++*switch_count;
\r\n
\r\n                 prepare_task_switch(rq, next);
\r\n                 prev = context_switch(rq, prev, next);
\r\n context_switch 建立了next的地址空间,进程描述符的active_mm指向进程使用的地址空间描述符,而mm指向进程拥有的地址空间描述符,通常二者是相同的。但是 内核线程没有自己的地址空间,mm一直为NULL。如果next为内核线程,context_switch保证next使用prev的地址空间。如果 next是一个正常的进程,context_switch使用next的替换prev的地址空间。
\r\n     struct mm_struct *mm = next->mm;
\r\n         struct mm_struct *oldmm = prev->active_mm;
\r\n
\r\n         if (unlikely(!mm)) {
\r\n                 next->active_mm = oldmm;
\r\n                 atomic_inc(&oldmm->mm_count);
\r\n                 enter_lazy_tlb(oldmm, next);
\r\n         } else
\r\n                 switch_mm(oldmm, mm, next);
\r\n 如果prev是一个内核线程或者正在退出的进程,context_switch在runqueue的prev_mm中保存prev使用的内存空间。
\r\n         if (unlikely(!prev->mm)) {
\r\n                 prev->active_mm = NULL;
\r\n                 WARN_ON(rq->prev_mm);
\r\n                 rq->prev_mm = oldmm;
\r\n         }
\r\n 调用switch_to(prev, next, prev)进行prev和next的切换。(参见“进程间的切换“)。

\r\n
\r\n #p#副标题#e#
\r\n 3:进程切换后的工作
\r\n (1)        finish_task_switch():
\r\n         struct mm_struct *mm = rq->prev_mm;
\r\n         unsigned long prev_task_flags;
\r\n
\r\n         rq->prev_mm = NULL;
\r\n
\r\n         prev_task_flags = prev->flags;
\r\n         finish_arch_switch(prev);
\r\n         finish_lock_switch(rq, prev);
\r\n         if (mm)
\r\n                 mmdrop(mm);
\r\n         if (unlikely(prev_task_flags & PF_DEAD))
\r\n                 put_task_struct(prev)
\r\n 如果prev是内核线程,runqueue的prev_mm保存prev的内存空间描述符。Mmdrop减少内存空间的使用数,如果该数为0,该函数释放内存空间描述符,以及与之相关的页表和虚拟内存空间。
\r\n finish_task_switch()还释放runqueue的自选锁,开中断。
\r\n (2)        最后
\r\n         prev = current;
\r\n         if (unlikely(reacquire_kernel_lock(prev) < 0))
\r\n                 goto need_resched_nonpreemptible;
\r\n         preempt_enable_no_resched();
\r\n         if (unlikely(test_thread_flag(TIF_NEED_RESCHED)))
\r\n                 goto need_resched;
\r\n schedule获取大内核块,重新使内核可以抢占,并且检查是否其他进程设置了当前进程的TIF_NEED_RESCHED,如果真,重新执行schedule,否则该程序结束。

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2870, 'filter-execution-threw-an-exception', 'Filter execution threw an exception', '2012-09-16 23:01:16', '2019-03-25 21:29:22', '
\r\n

\r\n 错误:

\r\n

\r\n HTTP Status 500 -

\r\n
\r\n type Exception report\r\n

\r\n message

\r\n

\r\n description The server encountered an internal error () that prevented it from fulfilling this request.

\r\n

\r\n exception

\r\n
\r\njavax.servlet.ServletException: Filter execution threw an exception\r\n
\r\n

\r\n root cause

\r\n
\r\njava.lang.NoSuchMethodError: ognl.SimpleNode.isEvalChain(Lognl/OgnlContext 
\r\n Z com.opensymphony.xwork2.ognl.OgnlUtil.isEvalExpression(OgnlUtil.java:223) com.opensymphony.xwork2.ognl.OgnlUtil.setValue(OgnlUtil.java:214) com.opensymphony.xwork2.ognl.OgnlValueStack.trySetValue(OgnlValueStack.java:186) com.opensymphony.xwork2.ognl.OgnlValueStack.setValue(OgnlValueStack.java:173) com.opensymphony.xwork2.ognl.OgnlValueStack.setParameter(OgnlValueStack.java:151) com.opensymphony.xwork2.interceptor.ParametersInterceptor.setParameters(ParametersInterceptor.java:292) com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:203) com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:9 com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249) com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:211) com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:9 com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249) com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:190) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249) org.apache.struts2.interceptor.MultiselectInterceptor.intercept(MultiselectInterceptor.java:75) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249) org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:90) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249) org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:243) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249) com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:100) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249) com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:141) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249) com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:145) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249) com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:171) com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:9 com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249) com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:176) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249) org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249) com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:192) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249) com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:187) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249) org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:54) org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:510) org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77) org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91)\r\n

\r\n note The full stack trace of the root cause is available in the Apache Tomcat/7.0.26 logs.

\r\n
\r\n

\r\n Apache Tomcat/7.0.26

\r\n

\r\n 原因:

\r\n

\r\n struts2.3.1.1 allows ognl3.0.2.jar + ognl3.0.2-source.jar + ognl3.0.1 at the same time . struts2.3.1.2 can only have ognl3.0.4, but remove other versions

\r\n

\r\n ognl3.0.4 is a must and can be the only ognl jar!

\r\n

\r\n 经过检测,发现lib中的ognl的版本是ognl-3.0.jar,然后我换成ognl3.0.4.jar,问题得到解决。

\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2871, 'assembly-language-environment-under-linux-build', 'Linux下汇编语言环境的搭建', '2012-09-12 05:35:18', '2019-03-25 21:29:22', '

\r\n       DOS下常用的工具MASM和TASM到Linux下就用不起来了,Linux有自己的汇编工具,而且种类非常的多。其中Gas可以算是标准配置,每一种 Linux中都包括有Gas,但是GAS采用的不是我们通常在DOS下采用的汇编语法,它采用的是AT&T的语法格式,与intel语法格式有很大的不同。
\r\n       如果要采用与DOS接近的语法格式,就必须用另一种汇编工具NASM,NASM基本与MASM相同,但也有不少地方有较大区别,特别涉及到操作系统原理时,与DOS可以说是截然不同。
\r\n
\r\n 一、NASM的安装
\r\n       由于笔者使用的ununtu版本的Linux系统,所以一ubuntu为例:
\r\n       打开终端:输入
\r\n       sudo apt-get install nasm
\r\n       安装即可。
\r\n
\r\n 二、Hello,world!的实现
\r\n       几乎所有的语言入门篇都是以“Hello,world!”为例,那么我也以Hello,world!为例开始。

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n;-------------NASM’s standalone Hello-World.asm for Linux --------\r\nsection .text\r\nextern puts\r\nglobal main\r\n\r\nmain:\r\npush dword msg ;stash the location of msg on the stack.\r\ncall puts ;call the "puts" routine (libc?)\r\nadd esp, byte 4 ;clean the stack?\r\nret ;exit.\r\n\r\nmsg:\r\ndb "Hello World!",
\r\n
\r\n

\r\n 编译:
\r\n nasm -f elf hello.asm
\r\n gcc -o hello hello.o

\r\n
\r\n 执行
\r\n ./hello
\r\n \"\"

\r\n
\r\n       说明:这个程序实际上是调用了,Linux系统的puts函数,原理与调用DOS下C语言的函数相同,先用Extern声明puts是外部函数,再把参数(即msg的地址)压入堆栈,最后Call函数实现输出。
\r\n       再来看一个程序:

\r\n  

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\nsection .text\r\nglobal main\r\n\r\nmain:\r\nmov eax,4 ;4号调用\r\nmov ebx,1 ;ebx送1表示stdout\r\nmov ecx,msg ;字符串的首地址送入ecx\r\nmov edx,14 ;字符串的长度送入edx\r\nint 80h ;输出字串\r\nmov eax,1 ;1号调用\r\nint 80h ;结束\r\nmsg:\r\ndb "Hello World!",0ah,0dh(编译同上一个程
\r\n
\r\n

\r\n
\r\n       (编译同上一个程序)
\r\n       这个程序与DOS程序十分相似,它用的是linux中的80h中断,相当于DOS下的21h中断,只是因为Linux是32位操作系统,所以采用了EAX、 EBX等寄存器。但是Linux作为一个多用户的操作系统与DOS又是有着非常大的区别的。要写出有特色的程序,不了解操作系统和硬件是不行的。
\r\n
\r\n Nasm常用命令介绍:
\r\n
\r\n Nasm -f elf hello.asm
\r\n
\r\n 将把hello.asm汇编成ELF object文件,而
\r\n
\r\n Nasm -f bin hello.asm -o hello.com
\r\n
\r\n 会把hello.asm汇编成二进制可执行文件hello.com
\r\n
\r\n Nasm -h
\r\n
\r\n 将会列出NASM命令行的完整说明。
\r\n
\r\n NASM不会有任何输出,除非有错误发生。
\r\n
\r\n -f 在Linux下主要有aout和ELF两种,如果你不确定你的Linux系统应该用AOUT还是ELF,可以在NASM目录中输入 File nasm ,如果输出nasm: ELF 32-bit LSB executable i386 (386 and up) Version 1表示是ELF,如果输出nasm: Linux/i386 demand-paged executable (QMAGIC)表示是aout。

\r\n #p#副标题#e#
\r\n NASM与MASM的主要不同:
\r\n
\r\n       首先与linux系统一样,nasm是区分大小写的,Hello与hello将是不同的标识符,如果要汇编到DOS或OS/2,需要加入UPPERCASE参数。
\r\n       其次,nasm中内存操作数都是以[ ]表示。
\r\n       在MASM中
\r\n foo equ 1
\r\n bar dw 2
\r\n mov ax,foo
\r\n mov ax,bar
\r\n       将被汇编成完全不同的指令,虽然它们在MASM中的表达方式完全一样。而NASM完全避免了这种混乱,它使用的是这样的规则:所有对内存的操作都必须通过[ ]来实现。例如上例中对bar的操作就要写成如下形式 mov ax,[bar]。由此可见,nasm中对offset的使用也是没有必要的(nasm中无offset)。Nasm对[ ]的使用与masm也有所不同,所有的表达式都必须写在[ ]中,下面举两个例子来说明:
\r\n
\r\n Masm Nasm
\r\n Mov ax,table[di]
\r\n Mov ax,[table+di]
\r\n
\r\n Mov ax,es:[di]
\r\n Mov ax,[es:di]
\r\n
\r\n Mov ax,[di]+1
\r\n Mov ax,[di+1]
\r\n
\r\n       Nasm 中不存储变量类型,原因很简单masm中通过[ ]寻址方式的变量也必须要指定类型。Nasm中不支持LODS, MOVS, STOS, SCAS, CMPS, INS, OUTS,只支持lodsb、lodsw等已经指定类型的操作。Nasm中不再有assume操作,段地址完全取决于存入段寄存器的值。
\r\n
\r\n 关于NASM的使用方法及语法还可以参阅NASM使用手册。
\r\n
\r\n 结论:
\r\n       我认为不论是在Windows/DOS下还是在Linux下完完全全用汇编编一个大型程序已经是不可能了,也不会有人愿意去这样做。在windows下我们 可以用VC,在Linux/Xwindows下我们可以用C甚至C++ Builder,但是像VC、C++ Builder之类的工具尽量隐藏了底层的调用,同时也阻隔了成为高手的机会,因为编出来的程序无法了解它的执行过程也就使编程中最重要的“可预测”性变 得很低。正因为如此汇编才有它存在的必要性,同时还有一个更重要的原因,正如《超级解霸》的作者梁肇新所说:“编程序的重点不是“编”,而是调试程序,理 论上的完美在实现的时候会遇到很多细节问题,这些问题必须调试才能解决。我的编程习惯是一天写五天调试,《超级解霸》是调试出来的,而不是写出来的。调试 就涉及到汇编的问题,不进行汇编级的调试是不彻底的,也不能让人放心。

\r\n
\r\n  

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2872, 'c-environment-under-ubuntu-build', 'ubuntu下C++环境的搭建', '2012-09-12 05:31:59', '2019-03-25 21:29:22', '

\r\n 打开终端,输入
\r\n sudo apt-get update
\r\n sudo apt-get install gcc g++

\r\n

\r\n 编译
\r\n g++ -o test  test.cpp
\r\n 运行
\r\n ./test

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2873, 'using-onclientclick-and-onclick-in-asp-net', 'Asp.Net中OnClientClick与OnClick的使用', '2012-09-10 20:29:39', '2019-03-25 21:29:22', '

\r\n       在ASP .NET web开发中,经常要用到控件的OnClientClick与OnClick事件,如果使用不当,经常会遇到一些意料之外的事情发生,让人摸不着头脑.下面就将我的一些经验总结道来:

\r\n

\r\n       首先我们要了解这两个事件:
\r\n       OnClientClick是客户端事件,OnClick是服务器端事件
\r\n       OnClientClick里面的是js的方法,如果返回true,页面postback
\r\n       OnClick的事件处理函数(后台),如果返回false,就不会postback

\r\n

\r\n       OnClientClick是客户端事件方法,一般采用JavaScript来进行处理.也就是直接在IE端运行.一点击就运行。
\r\n       OnClick事件是服务器端事件处理方法,在服务器端,也就是IIS中运行.点击按钮后,执行postback,再运行。

\r\n

\r\n       OnClientClick中我们常用来做一些客户端的检测.当然放在服务器也可以做同样的检测,但这样做的代价是与服务器进行交互,消耗资源,而且用户体验不好。

\r\n
\r\n

\r\n      一般我们用OnClientClick验证我们的提交数据,但是这个一定要返回ture或者false,即一定要加上return,否则OnClientClick失效当OnClientClick返回false时OnClick服务器端事件才被中止。当没有return时,当你的js验证有错误,也会跳过验证,直接执行服务器端事件OnClick。为了避免这样的错误,可以考虑用服务端验证这样就省去了OnClientClick事件,就不用考虑和OnClick的冲突了。但是从性能上,服务端验证,耗费了服务器资源,呵呵,一般是没问题的,只是和客户端验证比较而已,各有所长,各有所短。

\r\n

\r\n 例如下: try2.aspx:

\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n<%@ Page Language="C#" AutoEventWireup="true" CodeFile="try2.aspx.cs" Inherits="try2" %>\r\n\r\n<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\r\n\r\n<html xmlns="http://www.w3.org/1999/xhtml" >\r\n<head runat="server">\r\n    <title>无标题</title>\r\n    <script type="text/javascript">\r\n    function checkname()\r\n    {\r\n    var name=document.getElementById('TextBox1');\r\n    if(name.value=="")\r\n    {\r\n    alert("姓名不能为空!");\r\n    return false;\r\n    }\r\n    }\r\n    </script>\r\n</head>\r\n<body>\r\n    <form id="form1" runat="server">\r\n    <div>\r\n        &nbsp;\r\n        <table>\r\n            <tr>\r\n                <td>\r\n                    姓名:</td>\r\n                <td>\r\n        <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox></td>\r\n            </tr>\r\n            <tr>\r\n                <td >\r\n                </td>\r\n                <td >\r\n        <asp:Button ID="Button1" runat="server" Text="确定" OnClientClick="return checkname()" OnClick="Button1_Click" /></td>\r\n            </tr>\r\n        </table>\r\n    </div>\r\n    </form>\r\n</body>\r\n</html>\r\n
\r\n
\r\n

\r\n 后台代码:try2.aspx.cs:

\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\nusing System;\r\nusing System.Data;\r\nusing System.Configuration;\r\nusing System.Collections;\r\nusing System.Web;\r\nusing System.Web.Security;\r\nusing System.Web.UI;\r\nusing System.Web.UI.WebControls;\r\nusing System.Web.UI.WebControls.WebParts;\r\nusing System.Web.UI.HtmlControls;\r\n\r\npublic partial class try2 : System.Web.UI.Page\r\n{\r\n    protected void Page_Load(object sender, EventArgs e)\r\n    {\r\n\r\n    }\r\n    protected void Button1_Click(object sender, EventArgs e)\r\n    {\r\n        Response.Write("最后执行了!");\r\n    }\r\n}\r\n
\r\n
\r\n

\r\n      可测试发现如果try2.aspx 中OnClientClick="checkname()" ,没有"return ",客户端和服务器端都执行操作。

\r\n

\r\n       所以上例应带“return”,当姓名输入为空时,不至于执行服务器端的"Button1_Click"事件。即OnClientClick="return checkname()"     。

\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2874, '12-fun-c-interview-questions', '12个有趣的C语言面试题', '2012-09-10 04:34:39', '2019-03-25 21:29:22', '
\r\n 1.gets()函数
\r\n 问:请找出下面代码里的问题:

\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n    #include <stdio.h>\r\n    #include <cstring>\r\n    int main(void)\r\n    {\r\n        char buff[10];\r\n        memset(buff,0,sizeof(buff));\r\n\r\n        gets(buff);\r\n        printf("n The buffer entered is [%s]n",buff);\r\n        return 0;\r\n    }
\r\n
\r\n
\r\n \"\"
\r\n
\r\n 答:上面代码里的问题在于函数gets()的使用,这个函数从stdin接收一个字符串而不检查它所复制的缓存的容积,这可能会导致缓存溢出。这里推荐使用标准函数fgets()代替。
\r\n
\r\n 2.strcpy()函数

\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n    #include <stdio.h>\r\n    #include <cstring>\r\n    int main(int argc, char *argv[])\r\n    {\r\n        int flag = 0;\r\n        char passwd[10];\r\n\r\n        memset(passwd,0,sizeof(passwd));\r\n\r\n        strcpy(passwd, argv[1]);\r\n\r\n        if(0 == strcmp("LinuxGeek", passwd))\r\n        {\r\n            flag = 1;\r\n        }\r\n\r\n        if(flag)\r\n        {\r\n            printf("n Password cracked n");\r\n        }\r\n        else\r\n        {\r\n            printf("n Incorrect passwd n");\r\n\r\n        }\r\n        return 0;\r\n    } 
\r\n
\r\n
\r\n 问:下面是一个简单的密码保护功能,你能在不知道密码的情况下将其破解吗?\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n    $ ./psswd aaaaaaaaaaaaa\r\n\r\n    Password cracked 
\r\n
\r\n 答:破解上述加密的关键在于利用攻破strcpy()函数的漏洞。所以用户在向“passwd”缓存输入随机密码的时候并没有提前检查 “passwd”的容量是否足够。所以,如果用户输入一个足够造成缓存溢出并且重写“flag”变量默认值所存在位置的内存的长“密码”,即使这个密码无 法通过验证,flag验证位也变成了非零,也就可以获得被保护的数据了。例如:虽然上面的密码并不正确,但我们仍然可以通过缓存溢出绕开密码安全保护。
\r\n 要避免这样的问题,建议使用 strncpy()函数。
\r\n 作者注:最近的编译器会在内部检测栈溢出的可能,所以这样往栈里存储变量很难出现栈溢出。在我的gcc里默认就是这样,所以我不得不使用编译命令‘-fno-stack-protector’来实现上述方案。
\r\n
\r\n 3.main()的返回类型

\r\n 问:下面的代码能 编译通过吗?如果能,它有什么潜在的问题吗?
\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n    #include<stdio.h>\r\n    #include "stdlib.h"\r\n\r\n    void main(void)\r\n    {\r\n        char *ptr = (char*)malloc(10);\r\n\r\n        if(NULL == ptr)\r\n        {\r\n            printf("n Malloc failed n");\r\n            return;\r\n        }\r\n        else\r\n        {\r\n            // Do some processing\r\n            free(ptr);\r\n        }\r\n\r\n        return;\r\n    } 
\r\n
\r\n
\r\n 答:因为main()方法的返回类型,这段代码的错误在大多数编译器里会被当作警告。main()的返回类型应该是“int”而不是“void”。因为“int”返回类型会让程序返回状态值。这点非常重要,特别当程序是作为依赖于程序成功运行的脚本的一部分运行时。
\r\n #p#副标题#e#
\r\n 4.内存泄露
\r\n 问:下面的代码会导致内存泄漏吗?

\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n    #include <stdio.h>\r\n    #include "stdlib.h"\r\n\r\n    void main(void)\r\n    {\r\n        char *ptr = (char*)malloc(10);\r\n     \r\n        if(NULL == ptr)\r\n        {\r\n            printf("n Malloc failed n");\r\n            return;\r\n        }\r\n        else\r\n        {\r\n            // Do some processing\r\n        }\r\n     \r\n        return;\r\n    }\r\n
\r\n
\r\n
\r\n 答:尽管上面的代码并没有释放分配给“ptr”的内存,但并不会在程序退出后导致内存泄漏。在程序结束后,所有这个程序分配的内存都会自动被处理掉。但如果上面的代码处于一个“while循环”中,那将会导致严重的内存泄漏问题!
\r\n 提示:如果你想知道更多关于内存泄漏的知识和内存泄漏检测工具,可以来看看我们在Valgrind上的文章。

\r\n
\r\n 5.free()函数
\r\n 问:下面的程序会在用户输入'freeze'的时候出问题,而'zebra'则不会,为什么?

\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n    #include <stdio.h>\r\n    #include <cstring>\r\n    #include "stdlib.h"\r\n\r\n    int main(int argc, char *argv[])\r\n    {\r\n        char *ptr = (char*)malloc(10);\r\n\r\n        if(NULL == ptr)\r\n        {\r\n            printf("n Malloc failed n");\r\n            return -1;\r\n        }\r\n        else if(argc == 1)\r\n        {\r\n            printf("n Usage  n");\r\n        }\r\n        else\r\n        {\r\n            memset(ptr, 0, 10);\r\n\r\n            strncpy(ptr, argv[1], 9);\r\n\r\n            while(*ptr != 'z')\r\n            {\r\n                if(*ptr == ' ')\r\n                    break;\r\n                else\r\n                    ptr++;\r\n            }\r\n\r\n            if(*ptr == 'z')\r\n            {\r\n                printf("n String contains 'z'n");\r\n                // Do some more processing\r\n            }\r\n\r\n           free(ptr);\r\n        }\r\n\r\n        return 0;\r\n    } 
\r\n
\r\n
\r\n 答:这里的问题在于,代码会(通过增加“ptr”)修改while循环里“ptr”存储的地址。当输入“zebra”时,while循环会在执行前 被终止,因此传给free()的变量就是传给malloc()的地址。但在“freeze”时,“ptr”存储的地址会在while循环里被修改,因此导 致传给free()的地址出错,也就导致了seg-fault或者崩溃。
\r\n
\r\n 6.使用_exit退出
\r\n 问:在下面的代码中,atexit()并没有被调用,为什么?

\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n    #include<stdio.h>\r\n    #include <stdlib.h>\r\n\r\n    void func(void)\r\n    {\r\n        printf("n Cleanup function called n");\r\n        return;\r\n    }\r\n\r\n    int main()\r\n    {\r\n        int i = 0;\r\n\r\n        atexit(func);\r\n\r\n        for(;i<0xffffff;i++);\r\n\r\n        _exit(0);\r\n		return 0;\r\n    } 
\r\n
\r\n
\r\n 这是因为_exit()函数的使用,该函数并没有调用atexit()等函数清理。如果使用atexit()就应当使用exit()或者“return”与之相配合。
\r\n#p#副标题#e#
\r\n7.void*和C结构体
\r\n问:你能设计一个能接受任何类型的参数并返回interger(整数)结果的函数吗?
\r\n答:如下:

\r\nint func(void *ptr) 
\r\n如果这个函数的参数超过一个,那么这个函数应该由一个结构体来调用,这个结构体可以由需要传递参数来填充。
\r\n
\r\n8.*和++操作
\r\n问:下面的操作会输出什么?

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n    #include<stdio.h>\r\n\r\n    int main(void)\r\n    {\r\n        char *ptr = "Linux";\r\n        printf("n [%c] n",*ptr++);\r\n        printf("n [%c] n",*ptr);\r\n\r\n        return 0;\r\n    } 
\r\n
\r\n
\r\n答:输出结果应该是这样:
\r\n\"\"
\r\n
\r\n为什么?
\r\n      因为“++”和“*”的优先权一样,所以“*ptr++”相当于“*(ptr++)”。即应该先执行ptr++,然后才是*ptr,所以操作结果是“L”。第二个结果是“i”。
\r\n
\r\n9.修改代码片段(或者只读代码)
\r\n问:下面的代码段有错,你能指出来吗?

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n    #include<stdio.h>\r\n\r\n    int main(void)\r\n    {\r\n        char *ptr = "Linux";\r\n        *ptr = 'T';\r\n\r\n        printf("n [%s] n", ptr);\r\n\r\n        return 0;\r\n    } 
\r\n
\r\n
\r\n答:这是因为,通过*ptr = ‘T’,会改变内存中代码段(只读代码)“Linux”的第一个字母。这个操作是无效的,因此会造成seg-fault或者崩溃。
\r\n
\r\n10.会改变自己名字的进程
\r\n问:你能写出一个在运行时改变自己进程名的程序吗?
\r\n答:参见下面这段代码:

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n    #include <stdio.h>\r\n    #include "stdlib.h"\r\n    #include "string.h"\r\n    int main(int argc, char *argv[])\r\n    {\r\n        int i = 0;\r\n        char buff[100];\r\n\r\n        memset(buff,0,sizeof(buff));\r\n\r\n        strncpy(buff, argv[0], sizeof(buff));\r\n        memset(argv[0],0,strlen(buff));\r\n\r\n        strncpy(argv[0], "NewName", 7);\r\n\r\n        // Simulate a wait. Check the process\r\n        // name at this point.\r\n        for(;i<0xffffffff;i++);\r\n\r\n        return 0;\r\n    } 
\r\n
\r\n
\r\n#p#副标题#e#
\r\n11.返回本地变量的地址
\r\n问:下面代码有问题吗?如果有,该怎么修改?

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n    #include<stdio.h>\r\n\r\n    int* inc(int val)\r\n    {\r\n      int a = val;\r\n      a++;\r\n      return &a;\r\n    }\r\n\r\n    int main(void)\r\n    {\r\n        int a = 10;\r\n        int *val = inc(a);\r\n        printf("n Incremented value is equal to [%d] n", *val);\r\n        return 0;\r\n    } 
\r\n
\r\n
\r\n答:尽管上面的程序有时候能够正常运行,但是在“inc()”中存在严重的漏洞。这个函数返回本地变量的地址。因为本地变量的生命周期就是 “inc()”的生命周期,所以在inc结束后,使用本地变量会发生不好的结果。这可以通过将main()中变量“a”的地址来避免,这样以后还可以修改 这个地址存储的值。
\r\n
\r\n12.处理printf()的参数
\r\n问:下面代码会输出什么?

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n    #include<stdio.h>\r\n\r\n    int main(void)\r\n    {\r\n        int a = 10, b = 20, c = 30;\r\n        printf("n %d..%d..%d n", a+b+c, (b = b*2), (c = c*2));\r\n\r\n        return 0;\r\n    } 
\r\n
\r\n
\r\n答:输出结果是:
\r\n\"\"
\r\n这是因为C语言里函数的参数默认是从右往左处理的,输出时是从左往右。
\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2875, 'talk-about-the-context-for-tomcat-deployment-methods', '谈谈tomcat用context部署的方法', '2012-09-10 01:37:52', '2019-03-25 21:29:22', '

\r\n       首先为什么要使用Context来部署程序,因为各位都不想单纯的把自己开发的网站都堆在一个tomcat的webapp文件夹下面,希望在任意位置存放自己网站的位置,通过简单的配置来完成部署。

\r\n

\r\n     1:创建项目,配置好自己的web.xml文件(我头大了一天原来就是这个该死的东西错了,大家一定要注意)

\r\n

\r\n     一下给出一个简单的web.xml范例
\r\n  

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n<?xml version="1.0" encoding="UTF-8"?>\r\n\r\n<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">\r\n\r\n<web-app>\r\n\r\n        <display-name>notebook</display-name>\r\n\r\n        <welcome-file-list>\r\n\r\n                <welcome-file>index.jsp</welcome-file>\r\n\r\n        </welcome-file-list>\r\n\r\n</web-app>
\r\n
\r\n

\r\n 具体每一行什么意思我就不具体解释了,大家自己去查

\r\n

\r\n 接下来就是传说中的server.xml文件的配置了,具体如下:

\r\n

\r\n 在</Context>标签之后,</HOST>标签之前加入如下一段话

\r\n

\r\n <Context path="/notebook" docBase="D:/notebook" debug="0">

\r\n

\r\n </Context>

\r\n

\r\n path为你所部署的url索引,在访问的时候使用,如:http://localhost:8080/notebook

\r\n

\r\n docBase(注意大小写) 你所要指向的目录名称,xml文件放在web-inf文件夹下(这个我就不用说了吧)。

\r\n

\r\n 这样你就基本上配置成功了,运行startup.bat来测试运行吧,好了同学祝你成功。。

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2876, 'the-first-programming-language-who-would-it-be', '第一门编程语言选谁?', '2012-09-06 07:35:13', '2019-03-25 21:29:22', '

\r\n Are You Ready? Go!
\r\n ——第一门编程语言选谁?
\r\n 作者 北理工教师金旭亮

\r\n  

\r\n

\r\n       这篇文章是专门针对大学低年级学生(和其他软件开发初学者)写的,如果你己经是研究生或本科高年级学生,请将这篇文章转发给你的师弟或师妹,希望这篇文章 能够帮助他们少走弯路,顺利地迈入软件开发的大门;如果您是一位有经验的软件开发者,或者是关注计算机教育的同行,也敬请提出宝贵意见。
\r\n       最近,台湾知名技术专家蔡学镛先生写了一本《编程ING》,宣称“人人都能学会程序设计”。作为一名IT教育工作者,这本书引发了我的兴趣,翻看之后,共鸣之处不少,结合国内计算机教育的现状,产生了颇多感触,于是就有了这篇小文。

\r\n

\r\n 一、为什么学生视编程为畏途?

\r\n

\r\n 先当学生后当老师,不知不觉之中我在大学里己“混”了十多年,我发现,进入计算机专业就读的学生,最初至少有一大半对真实的软件开发根本不了解,是“一张白纸”,不幸的是,学了四年之后,许多张“白纸”又变成了许多罐“浆糊”,带着对软件开发可能是畏惧也可能是无所谓但绝对不是喜欢的感触离开校园。

\r\n

\r\n 编程真的那么没劲?那么难和枯燥?

\r\n

\r\n 我写了将近二十年的代码,虽然不靠编程吃饭,但也似乎勉强可算是个老程序员,我对编程的看法可总结为两句:何以解忧,唯有编程!我经常在想一个问题:编程其实是很有趣很好玩很实用并很有成就感的一件事,为什么会有这么多的学生视编程为畏途?而我们的计算机教育,为什么在打掉学生对编程的兴趣方面“如此成功”?

\r\n

\r\n 蔡学镛先生在《编程ING》给出了一张图:

\r\n

\r\n  

\r\n

\r\n  \"\"

\r\n

\r\n  

\r\n

\r\n 图 1 正向兴趣循环是学习的关键

\r\n

\r\n 我认为这张图道出了问题的关键——学习过程中的“正向”兴趣循环是否成功地建立。

\r\n

\r\n 强烈的兴趣与不断获得的成就感是整个学习过程的“引擎”,它为学生完成整个学习任务提供源源不断的强大动力。有无数的事实支持这个观点。

\r\n

\r\n 传统的教学观点认为,本科的主要教育目标之一是为学生在本专业领域未来的发展“打下扎实的理论与实践基础”,所以从一开始就要“严格要求”,“科学训练”。

\r\n

\r\n 这个观点不能说错,但我认为,我们的计算机教育,尤其是针对初学者的教育,首要的任务是引发兴趣。没有兴趣,一切免谈。

\r\n

\r\n 我所了解的事实是:计算机专业的学生有不少视编程为畏途。其原因在于我们的现有计算机教学方式从一开始就给了这些学生“痛苦”的编程体验,不幸的是,这种体验在后期枯燥的专业课学习中不断得到强化,学生最终对编程敬而远之或畏之如虎。

\r\n

\r\n 事实上,教育学研究早己指出,成功的高效的教学应该是这样的:循序渐进,由浅入深,步步为营,兴趣导向。

\r\n

\r\n 教师的职责,不是将知识“灌入”学生的大脑,首要的任务是引发学生的兴趣,鼓励他们去探索未知的领域,主动地学习和吸收知识,培养技能,积累经验。在这个学 习过程中,教师要成为一名优秀的导航员,给学生绘出航线,鼓励他们出海远航,解决他们在航行中所遇到的困难,并帮助学生建立学习的“正向”兴趣循环。

\r\n

\r\n 对编程的“第一印象”很重要啊!由此,引发了一个很有趣的问题——应该选择哪一门语言作为学生的第一门编程语言?
\r\n #p#副标题#e#

\r\n

\r\n 二、你学的第一门编程语言是什么?

\r\n

\r\n 在国内的大学中,当前大多数选用C作为学生的第一门编程语言。这其实并没有太大的问题,C的重要性无须我多说。其实问题的关键不在于选择C教学,而在于以哪种方式去教。

\r\n

\r\n 很不幸,国内许多C语言的教材都将主要的精力放在对C语法细节的介绍上,课程考核方式又很古板——很多院校采用闭卷考试,出一堆的选择题和填空题。典型的题目是将一段代码砍掉一两句,让学生“填空”。有哪位高手是通过做这些“填空题”学会编程的?上机也流于形式,让学生反复折腾几个“黑底白字”的“玩具般 的”小程序,学了一个学期,学生连一个有点用的程序都写不出来……

\r\n

\r\n 这种僵化的教学方式,足以毁掉多数学生对编程的兴趣。

\r\n

\r\n  我个人认为,C不应该成为针对大多数学生所讲授的第一门编程语言,我们的教学体系,应该给学生提供更多的选择。

\r\n

\r\n 针对初学者所讲授的第一门编程语言,应该具有以下的特点:

\r\n

\r\n (1)必须是“有趣”的,能诱导人去“动手”和“思考”。

\r\n

\r\n (2)需要对初学者屏蔽不必要的底层技术细节,以免分散他们的注意力。

\r\n

\r\n (3)这种语言必须足够简单,但同时又具备足够的能力编写出实用的程序,从而让学生能比较容易地获得成就感,感悟到软件开发的魅力。

\r\n

\r\n (4)这种语言必须能充分地体现现代软件开发的基本思想和技术成果,为学生进一步深入学习打下基础

\r\n

\r\n (5)花在这门编程语言上的时间和精力是有回报的,掌握了它,就掌握了一个强大的工具,可以在今后的学习中使用这个工具进行实践和创造。

\r\n

\r\n 另外,这门编程语言的学习,应该有助于初学者正确理解与体会到以下的编程思想:

\r\n

\r\n (1)分而治之:将大问题切分为小问题。

\r\n

\r\n (2)组件化与模块化:以搭积木的方式“构建”出软件系统。

\r\n

\r\n (3)算法思想:针对实际问题建立数学模型,设计计算机算法,最终编程解决问题。

\r\n

\r\n 同时,这门编程语言的学习,应能有效地培养出以下的编程基本功:

\r\n

\r\n (1)调试代码的能力

\r\n

\r\n (2)撰写可读性强、扩充性好、易于复用的优质代码的能力,培养良好的编程习惯

\r\n

\r\n (3)查找技术资源与阅读技术文档的能力

\r\n

\r\n          也许一门编程语言的学习无法达到上述的所有要求,但组合几种不同的编程语言就差不多了。下面,我介绍几种适合于初学者入门的编程语言。
\r\n  

\r\n

\r\n 三、适合于入门的脚本编程语言

\r\n

\r\n 为了教初学者学会编程,蔡学镛先生的《编程ING》选择了REBOL编程语言,这个语言确实比较简单,而且蔡先生的书图文并貌,用它来训练编程的基本技能很合适,但REBOL这门语言似乎过于小众化了一些,而且书中缺乏有力的能引发初学者兴趣的应用实例。

\r\n

\r\n 依据我的经验,如果初学者能动手写出几个有用的实例,他喜欢上编程的可能性会大大增加。

\r\n

\r\n 以下是我粗略归纳的很容易引发学生成就感的几个技术领域:

\r\n
    \r\n
  1. \r\n

    \r\n 图形图像与动画、多媒体

    \r\n
  2. \r\n
  3. \r\n

    \r\n 游戏

    \r\n
  4. \r\n
  5. \r\n

    \r\n 网络应用

    \r\n
  6. \r\n
  7. \r\n

    \r\n 拥有可视化界面的桌面应用程序

    \r\n
  8. \r\n
  9. \r\n

    \r\n 能跑在手机上的应用程序

    \r\n
  10. \r\n 就我个人看法,第一门语言比较适合采用脚本式的编程语言。\r\n
\r\n

\r\n Python:认识编程是怎么回事,训练基本编程技能

\r\n

\r\n 国外有许多人非常推崇Python(http://www.python.org),认为它是最适合初学者学习的一门编程语言。

\r\n

\r\n Python是一种动态编程语言,语法简洁易学,本身是开源的,Python程序可以运行于几乎所有主流的操作系统之上。

\r\n

\r\n 对于初学者而言,使用Python可以学习基本的编程知识(比如学会编写分支、循环语句),体会动态编程语言的特点,并理解类和对象等面向对象编程的基本知识。#p#副标题#e#

\r\n

\r\n 但针对国内的实际情况,使用Python存在着一些问题:

\r\n

\r\n (1)官方提供了一个交互式的开发环境IDLE,易于使用,但要开发拥有可视化界面的程序比较麻烦,其他厂商的开发环境也不太成熟稳定。

\r\n

\r\n (2)缺少合适的中文教材,与其他语言相比,在国内应用也并不算广。  个人观点:使用Python对初学者进行基本编程技能的训练还是比较合适的,但在使用它入门之后,还必须学习其他的编程语言。

\r\n

\r\n MATLAB和Scilab:训练算法的设计与编程实现能力

\r\n

\r\n 学习、应用和设计各种算法,培养为各种问题建立数学模型的能力,这对于软件开发而言非常重要,我国己在高中数学教学中引入了算法,并将其纳入了高考的考试内容,这是件好事。

\r\n

\r\n 当前高中新课标数学课本中,使用的是由法国国家信息自动化研究院(INRIA)开发的Scilab(http://www.scilab.org/),这个软件与大学里流行的MATLAB高度类似,是学习算法的好工具。

\r\n

\r\n 比较遗憾的是,Scilab也缺少足够的中文资料,并且由于高考数学仅考察简单的算法流程图,占分很少,因此大多数的高中都不会对这块投入太大力气,学生的算法思想和数学建模能力无法得到比较充分的训练,这个任务只能留到大学来完成了。

\r\n

\r\n 使 用Scilab或MATLAB作为第一门编程语言是完全可以的,与Python类似,Scilab或MATLAB编程采用交互式的运行方式(图2),编程 语法也很简易,通过它同样能培养出基本的编程技能,特别是它们强大的数学图形功能,对学生吸引力很强,Scilab或MATLAB编程对他们数学能力与算 法设计应用能力的训练无以伦比,这种能力会为学生未来在学术研究领域的发展提供强劲动力。

\r\n

\r\n  \"\"

\r\n

\r\n  

\r\n

\r\n 图 2  Scilab交互式编程环境

\r\n

\r\n Office+VBA:用VBA代码控制Office,让各种工作自动化

\r\n

\r\n 几 乎所有大学都开设有《计算机基础》这门课程,其中大多都会讲授微软Office软件包的使用。但当前这门课程教学方式是存在问题的,比如我看到过一些考试 试题,考核学生是否记住了Word的某些操作快捷键,这完全是本末倒置!其实,将本课程教学内容略作改革,完全可以用于培养学生的编程技能,其中的关键在 于加强或新增以下几个内容:

\r\n

\r\n (1)使用Excel进行数据分析,讲授Excel中功能强大的各种函数用法及数据的可视化呈现,这不仅实用,而且能有效地培养学生处理与理解数据的能力,而程序本质上不就是完成信息加工处理的工作吗?

\r\n

\r\n (2)使用Access存储与检索数据,这能让学生掌握数据库使用的基础知识,形成对数据库技术的感性认识。

\r\n

\r\n (3)Visual BasicFor Application(VBA)编程:VBA是一种脚本式的编程语言,在Office软件包中具有“控制一切”的能力,使用它进行编程的最大好处时能让 学生体会到——原来很多操作均可以一键“自动化”,并且在实现这种“自动化”的过程中拥有成就感。

\r\n

\r\n Processing编程语言:体会图形与动画的魅力

\r\n

\r\n 国内可能有很多人不知道Processing这个编程语言(http://www.processing.org/),其实它己有10多年的历史,由美国CaseyReas教授与 Ben Fry所设计,可用于构造丰富多彩的交互式应用软件。

\r\n

\r\n 与其它编程语言相比,Processing最强悍之处在于它的图形图像及动画编程功能。而在整个计算机技术领域中,这一块无疑是最吸引人的技术领域之一。#p#副标题#e#

\r\n

\r\n 虽 说磨刀不误砍柴功,但有不少编程语言在能够真正“砍柴(即动手开发真正有用的程序)”之前,需要太长的时间“磨刀(学习语法,掌握开发工具、阅读API文 档等等)”,而Processing就不存在这个问题,它的编程语法与Java一致,但比Java简洁得多,另外,与复杂的IDE如Eclipse、 Visual Studio之类相比,Processing的编程环境非常简单,这有助于学习者将主要精力用于创作上,并鼓励他们大胆地进行开发实践。

\r\n

\r\n  \"\"

\r\n

\r\n  

\r\n

\r\n 图 3 Processing编程环境

\r\n

\r\n Processing提供了一批直观、简洁而功能强大的图形图像函数,学习者仅需花少量时间学习就能立即投入到创作之中,而它所提供的大量可运行实例,能有效地激发学习者的想象力。

\r\n

\r\n Processing具有很强的可扩展性(现在已经有一百多个库可用了),特别地,Processing内置了对于Android的支持,Processing程序能够跑在Android手机上,这大大地增加了它的吸引力。

\r\n

\r\n 也许不少国内高校目前还无法开设Processing课程,但事实上大学生们是完全可以自学的,Processing网站上有足够的学习资源和示例,唯一比较遗憾的是这些资源都是英文的。

\r\n

\r\n Small Basic:适合“零编程基础”人的编程语言

\r\n

\r\n 在 中国,有不少人是通过Basic语言迈入编程的大门的,特别是微软在上个世纪所推出的Visual Basic,更被视为Windows桌面编程最佳入门语言,只可惜这个优势在其后继版本Visual Basic.NET中己经不复存在,从功能上说,现在的Visual Basic.NET与C#基本一致,付出的代价是Visual Basic.NET语言本身的复杂程度也变得与C#是同一级别的了,而后者的使用者要比前者多得多,与其学Visual Basic.NET,不如直接学C#。

\r\n

\r\n 这里,我想介绍的是微软所推出的另一种Basic编程语言——SmallBasic(http://www.smallbasic.com/)。

\r\n

\r\n 微软公司在其软件用户友好性方面一直做得非常出色,Small Basic沿袭了这个特色,其开发环境的易用性超过前面介绍的所有编程语言,并提供智能的编程帮助(图4)。

\r\n

\r\n  

\r\n

\r\n  \"\"

\r\n

\r\n  

\r\n

\r\n 图 4 Small Basic的智能编程环境

\r\n

\r\n #p#副标题#e#

\r\n

\r\n Small Basic提供了两个强大的“窗口”对象——TextWindow(用于输出文本)和GraphicsWindow(用于绘图),特别有趣的,它从历史悠 久的Logo语言中得到借鉴,提供了一个小乌龟(Turtle)对象,通过简单的指令就可以命令这只小乌龟(Turtle)在屏幕上“爬”出各种图案来, 确实有趣好玩。

\r\n

\r\n 我个人看法,Small Basic是一个非常好的针对“零基础”人的入门编程语言,特别适合于年纪较小的学习者(比如初高中学生),也可供非计算机专业(比如文科专业)的大学生编程快速入门。

\r\n

\r\n HTML 5 + JavaScript:互联网时代的主流编程语言

\r\n

\r\n 各种脚本编程语言中,我想介绍的最后一种是JavaScript。

\r\n

\r\n JavaScript早就是Web客户端事实上的主流编程语言,它的运行环境是浏览器,当前所有的计算机和绝大部份智能手机都至少安装有一种浏览器,JavaScript程序“到处都可以运行”。

\r\n

\r\n JavaScript程序的编写极为简单,就算使用Windows记事本,写上几段也不算太麻烦。

\r\n

\r\n JavaScript 早期存在的问题主要是各浏览器厂商自行其是,标准不统一,而且缺少必要的调试工具,但这些问题现在己大大缓解。以开发工具来说,主流的IDE纷纷加入对 JavaScript程序开发与调试的支持,比如Visual Studio 2010/2012就做得很出色,另外,随着我们进入移动互联网的时代,HTML 5是唯一能被各厂商接受的标准,与此对应,JavaScript也正在走向标准化。

\r\n

\r\n 与 Python等语言类似,JavaScript也可归入动态脚本语言的范畴,语法简单,同样支持面向对象的编程方式,但JavaScript的使用远比 Python等语言广,诸如jQuery之类的各种JavaScript库如雨后春笋般地出现,其功能无所不包,甚至在服务端JavaScript也大展 身手,比如一个事件驱动的服务端JavaScript运行环境——Node.js(http://nodejs.org/)就相当引人注目

\r\n

\r\n JavaScript在HTML 5规范中拥有核心的地位,可以用JavaScript完成很多的工作:

\r\n
    \r\n
  • \r\n

    \r\n  基于canvas可编程绘制二维的图形,使用SVG通过DOM可构造交互式的应用

    \r\n
  • \r\n
  • \r\n

    \r\n  HTML 5的audio和video元素可以播放音频和视频,所以可以用JavaScript开发多媒体应用

    \r\n
  • \r\n
  • \r\n

    \r\n  Geolocation、Communication和WebSocket  API支持编写地理感知的互联网应用程序

    \r\n
  • \r\n
  • \r\n

    \r\n  ……

    \r\n
  • \r\n
\r\n

\r\n 为 了抢战先机,各大浏览器厂商都在不断地完善自己的产品,争取能支持更多的HTML 5特性,而且智能手机的两大主流操作系统iOS和Android都可以运行使用JavaScript编写的Web应用。微软也在紧跟这个潮流,在其最新的 Windows 8中,可以使用JavaScript编写Metro风格的Windows 8 应用。

\r\n

\r\n 由此看来,JavaScript可谓是风光无限。

\r\n

\r\n 我 强力推荐在高校中推广JavaScript课程,其实国内高校在这方面也已经有一定基础了,比如许多高校都开设有《网页设计基础》这门课程,只需更新一下 课程的教学内容,加入HTML 5和JavaScript的内容,并改革教学方式(比如千万不要再采用闭卷考试的方式要学生去背各种HTML标记的含义……),就能让学生跟上时代的步 伐,而且我相信JavaScript一定会比C更能吸引学生,激发他们对软件开发的兴趣。

\r\n

\r\n 四、以编译型的语言作为入门级编程语言

\r\n

\r\n 虽然我更趋向于使用脚本语言完成初学者的编程启蒙任务,但我们同样可以使用编译型的编程语言完成这一任务。

\r\n

\r\n C就不用我多说了,相信有很多牛人是从C出来的。

\r\n

\r\n 另两门非常重要的编译型语言是Java和C#,我的看法是即使不把它们当成计算机专业的第一门编程语言,至少也应该在计算机专业一、二年级安排这两个编程语言的选修课程。

\r\n

\r\n 下面先说说Java。

\r\n

\r\n Java:“人多势众”的主流面向对象编程语言

\r\n

\r\n 据说全世界的软件开发人员中,Java程序员的总人数名列前茅。人多说明市场需求量大,Java技术应用广。

\r\n

\r\n 采 用Java作为第一门编程语言,比较适合于计算机专业的学生,能让他们一开始就能受到面向对象编程风格与思想的熏陶,之后他们可以再倒过来去学C。而不是 象现在这样,先学C再学Java,谈到C再顺便说说C++,现在许多院校开设有C++课程,其实这些年来C++应用的领域被不断地压缩,而且C++语法过 于复杂,开发效率低,除了部分有需求有兴趣的学生,不适合多数学生学习。

\r\n

\r\n Java入门主要分为两个阶段:一是Java语法与OOP思想的领悟,二是JDK中各个Java类及相关技术(比如多线程、序列化等)的学习。

\r\n

\r\n Java是Android的主要开发语言,因此学生在入门之后,可以进一步地开发基于Android的手机应用,引导学生进入移动互联的时代,具有很强的实用性,这点往往能触发学生学习Java的强劲动力。

\r\n

\r\n Java天生与“开源”两字联系在一起,掌握Java之后,学生可以迈入开源的世界,探索各种丰富的开源应用和技术的奇思妙想,这对于开拓学生的视野非常有好处,并且能直接地帮助其就业。

\r\n

\r\n 其实很多院校都开设了Java课程,我的建议不过就是将其提到大学一年级就讲授,并立即跟上J2EE和Android的后继课程。

\r\n

\r\n C# :面向对象编程语言的集大成者#p#副标题#e#

\r\n

\r\n 作为面向对象编程语言家族的后来者,C#有足够的机缘从前辈中汲取经验,这使得C#成为一个面向对象编程语言的集大成者。

\r\n

\r\n 与Java类似,C#比较适合作为计算机专业的入门级编程语言。C#开发通常使用微软自己研发的Visual Studio,与其他IDE相比,我认为Visual Studio是非常优秀的集成开发环境,即使是免费的版本,也拥有高度的智能性和良好的使用体验。

\r\n

\r\n 笔者曾经做过试验,直接带领计算机专业一年级学生在没有学C的前提下学习C#,也开设过全校的通识选修课,针对非计算机专业的学生讲授C#编程语言与.NET编程技术,都得到了良好的反馈。

\r\n

\r\n 以下是我总结出来的C#编程中几个很能引发学生兴趣的内容:

\r\n
    \r\n
  1. \r\n

    \r\n Windows Forms:可让学生迅速地开发出可视化的桌面应用程序,极具成就感。

    \r\n
  2. \r\n
  3. \r\n

    \r\n GDI+:通过简单的循环、递归的编程技巧,能够绘出漂亮的图案,并且可以移植到Web上,很吸引学生。

    \r\n
  4. \r\n
  5. \r\n

    \r\n ADO.NET:掌握它学生就可以开发简单的数据库应用程序,真正地写出一些有用的程序。

    \r\n
  6. \r\n
  7. \r\n

    \r\n Socket编程:让学生轻易地实现两台计算机互相交换信息,这个过程充满探索的乐趣。

    \r\n
  8. \r\n
\r\n

\r\n 以上几板斧下来,实践证明,能成功地引发很多学生对编程的兴趣,甚至“引诱”了不少学生决定跨专业报考计算机专业的研究生。

\r\n

\r\n 与Java相比,C#的问题是与微软公司绑得太紧,容易把学生局限于微软所构建的生态系统之中,影响其视野的开阔性。

\r\n

\r\n          就我个人观点,计算机专业的学生应该在大一,最晚推迟到大二,就掌握一门主流的通用型编程语言和开发工具(Java和C#是我当前推荐的两种编程语言), 并且在今后的专业学习中,使用它们把在后继计算机专业课中学到的理论知识应用于实践。这样一来,编程语言的学习就给计算机专业理论课的学习以强劲的推动, 而学生的开发能力也将随着开发实践的深入而不断增强,为其日后迈入业界或进入学术领域铺路。

\r\n

\r\n 五、结束语:与时俱进的计算机教学

\r\n

\r\n 计 算机是进步最快的技术领域之一,这就要求我们的计算机教学应该与时俱进并不断地调整。笔者从《计算机学会通讯》2012年第6期的一篇文章了解到,美国加 州大学伯克利分校己经开设了这样的课程:教学生使用Ruby On Rails之类的工具进行敏捷开发并在Amazon web Services上部署。

\r\n

\r\n “云计算”来了!

\r\n

\r\n  “云 计算”时代的来临,会对计算机教学的方式产生巨大的影响,笔者设想了一下,如果由教育部牵头,由国家投资支持组建一个“教育与科研云”,打造一个国家级的 教育公共平台,不走商业化的路,坚持让所有的在校学生和教师都能免费使用,努力推动各种的教学资源上移到云端,让更多的课程能用上云平台所提供的丰富资源 与强大计算能力,这将是一项利国利民的教育基础设施建设,从长远来说,对人的教育投资,是收益最大的投资。已经成为世界第二大经济体的中国,难道还拿不出 这笔钱和资源进行这个旨在为整个民族赢得未来的长线投资?

\r\n

\r\n 21世纪是人类信息技术突飞猛进并全面渗透到人类社会各领域的时代,在这样一个日益信息化的时代里,

\r\n

\r\n Are you ready?  Let’s Go!

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2877, 'js-effects-of-browser-title-bar-flashes', 'JS特效之浏览器标题栏闪烁', '2012-09-05 02:55:30', '2019-03-25 21:29:22', '
\r\n ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2878, 'about-the-hidden-input-tags-and-forms-of-commonly-used-tags-xiangjie', '关于input的hidden标签及表单常用标签的作用详解', '2012-09-05 02:35:36', '2019-03-25 21:29:22', 'Input表示Form表单中的一种输入对象,其又随Type类型的不同而分文本输入框,密码输入框,单选/复选框,提交/重置按钮等,下面一一介绍。
\r\n1,type=text
\r\n输入类型是text,这是我们见的最多也是使用最多的,比如登陆输入用户名,注册输入电话号码,电子邮件,家庭住址等等。当然这也是Input的默认类型。
\r\n参数name:同样是表示的该文本输入框名称。
\r\n参数size:输入框的长度大小。
\r\n参数maxlength:输入框中允许输入字符的最大数。
\r\n参数value:输入框中的默认值
\r\n特殊参数readonly:表示该框中只能显示,不能添加修改。
\r\n<form>
\r\nyour name:
\r\n<input type="text" name="yourname" size="30" maxlength="20" value="输入框的长度为30,允许最大字符数为20"><br>
\r\n<input type="text" name="yourname" size="30" maxlength="20" readonly value="你只能读不能修改">
\r\n</form>
\r\n
\r\n2,type=password
\r\n不用我说,一看就明白的密码输入框,最大的区别就是当在此输入框输入信息时显示为保密字符。
\r\n参数和“type=text”相类似。
\r\n<form>
\r\nyour password:
\r\n<input type="password" name="yourpwd" size="20" maxlength="15" value="123456">密码长度小于15
\r\n</form>
\r\n
\r\n3,type=file
\r\n当你在BBS上传图片,在EMAIL中上传附件时一定少不了的东西:)
\r\n提供了一个文件目录输入的平台,参数有name,size。
\r\n<form>
\r\nyour file:
\r\n<input type="file" name="yourfile" size="30">
\r\n</form>
\r\n
\r\n4,type=hidden
\r\n非常值得注意的一个,通常称为隐藏域:如果一个非常重要的信息需要被提交到下一页,但又不能或者无法明示的时候。
\r\n一句话,你在页面中是看不到hidden在哪里。最有用的是hidden的值。

\r\n<form name="form1">
\r\nyour hidden info here:
\r\n<input type="hidden" name="yourhiddeninfo" value="cnbruce.com">
\r\n</form>
\r\n<script>
\r\nalert("隐藏域的值是 "+document.form1.yourhiddeninfo.value)
\r\n</script>
\r\n
\r\n5,type=button
\r\n标准的一windows风格的按钮,当然要让按钮跳转到某个页面上还需要加入写JavaScript代码
\r\n<form name="form1">
\r\nyour button:
\r\n<input type="button" name="yourhiddeninfo" value="Go,Go,Go!" onclick="window.open('http://www.cnbruce.com')">
\r\n</form>
\r\n
\r\n6,type=checkbox
\r\n多选框,常见于注册时选择爱好、性格、等信息。参数有name,value及特别参数checked(表示默认选择)
\r\n其实最重要的还是value值,提交到处理页的也就是value。(附:name值可以不一样,但不推荐。)
\r\n<form name="form1">
\r\na:<input type="checkbox" name="checkit" value="a" checked><br>
\r\nb:<input type="checkbox" name="checkit" value="b"><br>
\r\nc:<input type="checkbox" name="checkit" value="c"><br>
\r\n</form>
\r\nname值可以不一样,但不推荐<br>
\r\n<form name="form1">
\r\na:<input type="checkbox" name="checkit1" value="a" checked><br>
\r\nb:<input type="checkbox" name="checkit2" value="b"><br>
\r\nc:<input type="checkbox" name="checkit3" value="c"><br>
\r\n</form>

\r\n#p#副标题#e#
\r\n7,type=radio
\r\n即单选框,出现在多选一的页面设定中。参数同样有name,value及特别参数checked.
\r\n不同于checkbox的是,name值一定要相同,否则就不能多选一。当然提交到处理页的也还是value值。
\r\n<form name="form1">
\r\na:<input type="radio" name="checkit" value="a" checked><br>
\r\nb:<input type="radio" name="checkit" value="b"><br>
\r\nc:<input type="radio" name="checkit" value="c"><br>
\r\n</form>
\r\n下面是name值不同的一个例子,就不能实现多选一的效果了<br>
\r\n<form name="form1">
\r\na:<input type="radio" name="checkit1" value="a" checked><br>
\r\nb:<input type="radio" name="checkit2" value="b"><br>
\r\nc:<input type="radio" name="checkit3" value="c"><br>
\r\n</form>
\r\n
\r\n8,type=image
\r\n比较另类的一个,自己看看效果吧,可以作为提交式图片
\r\n<form name="form1" action="xxx.asp">
\r\nyour Imgsubmit:
\r\n<input type="image" src="../blog/images/face4.gif">
\r\n</form>
\r\n
\r\n9,type=submit and type=reset
\r\n分别是“提交”和“重置”两按钮
\r\nsubmit主要功能是将Form中所有内容进行提交action页处理,reset则起个快速清空所有填写内容的功能。
\r\n<form name="form1" action="xxx.asp">
\r\n<input type="text" name="yourname">
\r\n<input type="submit" value="提交">
\r\n<input type="reset" value="重置">
\r\n</form>
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2879, 'talk-about-the-development-process-of-my-website', '谈谈我的网站的发展历程', '2012-09-05 02:26:52', '2019-03-25 21:29:22', '

[copy]talk-about-the-development-process-of-my-website[/copy]

今天早上,照例打开360站长工具查询收录情况,惊喜的发现百度的收录竟然突破了100,谷歌pr也升为了1,此时的我有种如释重负的感觉。回想新价值网(http://www.xinvalue.com)的发展历程,几多辛酸,几多波折。。。

      笔者最开始真正接触网站(拥有自己的网站)还是在大一下学期,在西校区的时候,那时不知从哪来的想法(现在也记不清了),看到各种丰富的网站,羡慕之余,突然有种拥有自己网站的冲动。想法是很重要的,现在的我也这么认为,正是这种想法的驱动,让我实现了从一无所知的菜鸟到草根站长的蜕变。于是,我便百度建网站,第一次接触网站知识,我被就繁杂的流程冲昏了头,什么域名啊,什么空间(虚拟主机)啊,什么FTP啊,对那时的我,简直是天方夜谭。我曾一度尝试放弃。尽管如此,还是挡不住我想拥有网站的冲动。

      这段时间,我虽不是很专注于它,但也时不时搜索这方面的信息。终于有一天,搜到了“免费自助建站”(这里要解释下,免费自助建站,就是别人免费给你提供一个二级域名甚至三级域名的子网站,一般都带有强制广告且空间大小有限制),一看到免费,我便顿时停住了,开始是不太相信,后来又忍不住尝试(或许大多数人和当时的我一样都有对免费情有独钟的心态吧),于是,我就这注册了一个(告诉大家也没啥,这个网站就是领地网(http://www.lingd.net/)),我注册的现在还在http://tewer.lingdi.net/(有需要的可以联系我QQ1035136784,现在我已经将它废弃了),开始使用之后,当时的我还是兴奋异常,以为自己终于有了属于自己的网站,可是当我发现页面底部有强制广告,网站访问量很少,百度也不收录时,心里便开始纠结了。于是,我就查找资料,才发现,原来百度只收录顶级域名,并且对于这种自助建站,百度有限制,所以笔者建议,大家如果想好好建一个网站,还是不要选此类建站服务。

      此后,不必多说,自助建站基本与我说再见了,这也是最没有技术含量的建站方式,甚至可以称为“傻瓜式建站”,貌似现在也还有很多这样的服务,笔者建议还是不要沉迷于这种所谓的“免费”,否则你的网站必定会误入歧途,至于原因,过来人应该都有同感,天下没有免费的午餐,你懂得。后来,笔者也陆续尝试过其它的建站方式,都不尽如人意,要么限制太多,要么强制广告,因此便没长久,在这里就不一一细说了,有兴趣的可以Q我,交流交流。笔者就谈谈正规的建站流程吧,算是分享一下笔者的浅见,让致力于建站的朋友也好少走一点弯路。

      首先,要选择好的服务商(IDC),一个好的IDC服务商可以让你的网站升值,因为它涉及到域名的解析速度,空间的稳定性以至于备案的流程等等。国内有很多好的IDC,像万网(www.net.cn)(应该没有不知道的吧),不过那你用不起的,想一些其他的服务优良,价格适宜的也有很多,笔者用的(www.idcbaidu.com)就很不错。好的IDC服务商是网站成功最重要的因素之一,而这点往往被贪图免费的初学者所忽视。

      第一步:网站程序。

      为什么把它放在第一,因为它才是网站的核心。这个看你的能力了,要有能力最好自己写,这样维护起来比较方便。不过,对于初学者,似乎不大可能。其实,网上有很多开源程序,比如,颇有盛名的wordpress,这是一个博客程序,如果你做博客,强烈建议用wordpress,他的用户群相当广,你可以免费得到很多插件,不过前提是,你对技术应该有一定的了解。其他的CMS的向帝国、织梦,论坛的像Discuz等等。

      第二步:域名注册。

      专业的解释就不用我说了吧,自己百度百科去。关于域名,这里面也有很深的学问,大到域名注册商,小到域名中介,域名交易等都有很大的商机,不过这不是我重点讨论的,关于它,有可能三天三夜也说不完。我要说的是如何让域名发挥它最大的价值。通俗的说,域名就是给IP另外取一个名字而已,这通过域名服务器(Domain Server)来解析。所以,当你确定了你的网站的主题(这点很重要,最好有唯一的主题,即你的网站是干什么的,最好不要面面俱到,这是门户网站(比如新浪、腾讯、搜狐、网易等,它们都很成熟了)做的,你比不来的,所以最好去某一方面的题材,把它做出自己的特色,这点,笔者也在努力),就应该选一个与你主题相关,要么谐音,要么意义相近的域名,这个可以为你的网站增色不少。

      第二步:域名备案。

      你可能会疑问,这也是关于域名的为什么还要单独列出来?因为他的重要性是不言而喻的。域名备案是工信部强制要求的,也就是说是法律层次的,你说重要不重要?严格上说,在国内,没有备案的网站在原则上都是非法的。说了这么多,无非想告诉大家,域名备案的重要性,即它不是可有可无的而是必须要做的,否则,你的网站随时都有被查封的看可能。关于如何备案,一般IDC服务商会提供相关手续,就不细说了。

      第三步:选择空间。

      其实,专业点,应该叫虚拟主机。顾名思义,空间就是你网站程序存放的地方,类似于你电脑上的硬盘。这个和域名名的选择最好一起。空间的选择也很有讲究,速度、质量、对程序的支持(ASP+ACCESS、ASP .NET+MSSQL、PHP+MYSQL等)都要考虑。

      第四步:上传程序。

      这一步,要等到域名备案通过以后\r\n再做,一般域名备案在20个工作日。域名备案通过后,就可以进行域名绑定(相当重要),将域名解析到主机,一般都有默认的测试页。绑定后,若在浏览器输入http://你的域名,如果可以访问默认页,恭喜你,绑定成功!这个时候,就可以通过FTP(这个自行百度百科其用法)删除默认文件,再将你的网站程序上传到网站空间。再次在浏览器输入http://你的域名,如果可以访问!OK,你的网站终于大功告成!至于后续的SEO,想搜索引擎提交获取收录等,笔者就不在赘述了,感兴趣可以Q我!

      哇!写了这么多,笔者也累了,如果你在建站方面正在迷茫,希望这篇文章可以帮到你,祝你成功!

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2880, 'september-2012-charts-the-tiobe-programming-language-objective-c-ranking-rises', '2012年9月TIOBE编程语言排行榜:Objective-C排名顺序上升', '2012-09-04 08:02:04', '2019-03-25 21:29:22', '      上月排名首位的C语言,本月继续领跑,并与第二名的Java的差距进一步拉大。
\r\n
\r\n      得益于iOS产品的Objective-C本月继续推进,稳居第三名的位置。但其与前两名的差距还有很大,由此可见,未来很长一段时间内,还没有语言能够撼动C和Java的地位。

\r\n
\r\n
\r\n
\r\n
\r\n
\r\n      由于TIOBE排行榜对于谷歌Go语言的统计算法存在一定的问题,导致Go甚至排在了谷歌另一个新语言Dart之后,前50名中未见其身影。因此,我们再来参考另一个语言排行版——Sourceforge语言指数
\r\n
\r\n      在该排名中,C、Java的名次和份额正好和TIOBE中的相反。其他排名前十的语言相差不大。Go语言排在第16位。

\r\n
\r\n
\r\n
\r\n
\r\n
\r\n      在网页脚本语言中,PHP是当之无愧的老大,占据了五分之一的份额。前五名脚本语言如下:
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n无论是TIOBE排行榜,还是Sourceforge语言指数,其排名数据都是基于互联网上有经验的程序员、课程和第三方厂商的数量,并使用热门搜索引擎所统计,只是反映某个编程语言的热门程度,并不能说明一门编程语言好不好,或者一门语言所编写的代码数量多少。
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2881, 'string-usage-in-c', 'C++中string的用法', '2012-08-31 03:37:54', '2019-03-25 21:29:22', '      之所以抛弃char*的字符串而选用C++标准程序库中的string类,是因为他和前者比较起来,不必担心内存是否足够、字符串长度等等,而且作为一个类出现,他集成的操作函数足以完成我们大多数情况下(甚至是100%)的需要。我们可以用 = 进行赋值操作,== 进行比较,+ 做串联(是不是很简单?)。我们尽可以把它看成是C++的基本数据类型。 
\r\n
\r\n      首先,为了在我们的程序中使用string类型,我们必须包含头文件 <string>。如下: 
\r\n#include <string> //注意这里不是string.h string.h是C字符串头文件 
\r\n
\r\n1.声明一个C++字符串 
\r\n声明一个字符串变量很简单: 
\r\nstring Str; 
\r\n这样我们就声明了一个字符串变量,但既然是一个类,就有构造函数和析构函数。上面的声明没有传入参数,所以就直接使用了string的默认的构造函数,这个函数所作的就是把Str初始化为一个空字符串。String类的构造函数和析构函数如下:
\r\na) string s; //生成一个空字符串s 
\r\nb) string s(str) //拷贝构造函数 生成str的复制品 
\r\nc) string s(str,stridx) //将字符串str内"始于位置stridx"的部分当作字符串的初值 
\r\nd) string s(str,stridx,strlen) //将字符串str内"始于stridx且长度顶多strlen"的部分作为字符串的初值 
\r\ne) string s(cstr) //将C字符串作为s的初值 
\r\nf) string s(chars,chars_len) //将C字符串前chars_len个字符作为字符串s的初值。 
\r\ng) string s(num,c) //生成一个字符串,包含num个c字符 
\r\nh) string s(beg,end) //以区间beg;end(不包含end)内的字符作为字符串s的初值 
\r\ni) s.~string() //销毁所有字符,释放内存 
\r\n都很简单,我就不解释了。 
\r\n
\r\n2.字符串操作函数 
\r\n这里是C++字符串的重点,我先把各种操作函数罗列出来,不喜欢把所有函数都看完的人可以在这里找自己喜欢的函数,再到后面看他的详细解释。 
\r\na) =,assign() //赋以新值 
\r\nb) swap() //交换两个字符串的内容 
\r\nc) +=,append(),push_back() //在尾部添加字符 
\r\nd) insert() //插入字符 
\r\ne) erase() //删除字符 
\r\nf) clear() //删除全部字符 
\r\ng) replace() //替换字符 
\r\nh) + //串联字符串 
\r\ni) ==,!=,<,<=,>,>=,compare() //比较字符串 
\r\nj) size(),length() //返回字符数量 
\r\nk) max_size() //返回字符的可能最大个数 
\r\nl) empty() //判断字符串是否为空 
\r\nm) capacity() //返回重新分配之前的字符容量 
\r\nn) reserve() //保留一定量内存以容纳一定数量的字符 
\r\no) [ ], at() //存取单一字符 
\r\np) >>,getline() //从stream读取某值 
\r\nq) << //将谋值写入stream 
\r\nr) copy() //将某值赋值为一个C_string 
\r\ns) c_str() //将内容以C_string返回 
\r\nt) data() //将内容以字符数组形式返回 
\r\nu) substr() //返回某个子字符串 
\r\nv)查找函数 
\r\nw)begin() end() //提供类似STL的迭代器支持 
\r\nx) rbegin() rend() //逆向迭代器 
\r\ny) get_allocator() //返回配置器 
\r\n下面详细介绍: 
\r\n
\r\n2.1 C++字符串和C字符串的转换 
\r\n      C++提供的由C++字符串得到对应的C_string的方法是使用data()、c_str()和copy(),其中,data()以字符数组的形式返回 字符串内容,但并不添加’ ’。c_str()返回一个以‘ ’结尾的字符数组,而copy()则把字符串的内容复制或写入既有的c_string 或 
\r\n字符数组内。C++字符串并不以’ ’结尾。我的建议是在程序中能使用C++字符串就使用,除非万不得已不选用c_string。由于只是简单介绍,详细介绍掠过,谁想进一步了解使用中的注意事项可以给我留言(到我的收件箱)。我详细解释。 
\r\n
\r\n2.2 大小和容量函数 
\r\n      一个C++字符串存在三种大小:
\r\na)现有的字符数,函数是size()和length(),他们等效。Empty()用来检查字符串是否为空。
\r\nb)max_size() 这个大小是指当前C++字符串最多能包含的字符数,很可能和机器本身的限制或者字符串所在位置连续内存的大小有关系。我们一般情况下不用关心他,应该大小足够我们用的。但是不够用的话,会抛出length_error异常。
\r\nc)capacity()重新分配内存之前 
\r\nstring所能包含的最大字符数。这里另一个需要指出的是reserve()函数,这个函数为string重新分配内存。重新分配的大小由其参数决定, 
\r\n默认参数为0,这时候会对string进行非强制性缩减。 
\r\n
\r\n      还有必要再重复一下C++字符串和C字符串转换的问题,许多人会遇到这样的问题,自己做的程序要调用别人的函数、类什么的(比如数据库连接函数Connect(char*,char*)),但别人的函数参数用的是char*形式的,而我们知道,c_str()、data()返回的字符数组由该字符串拥有,所以是一种const char*,要想作为上面提及的函数的参数,还必须拷贝到一个char*,而我们的原则是能不使用C字符串就不使用。那么,这时候我们的处理方式是:如果此函数对参数(也就是char*)的内容不修改的话,我们可以这样Connect((char*)UserID.c_str(), #p#分页标题#e#
\r\n(char*)PassWD.c_str()),但是这时候是存在危险的,因为这样转换后的字符串其实是可以修改的(有兴趣地可以自己试一试),所以除非调用的时候不对参数进行修改,否则必须拷贝到一个char*上去。当然,更稳妥的办法是无论什么情况都拷贝到一个char*上去。同时我们也祈祷现在仍然使用C字符串进行编程的高手们(说他们是高手一点儿也不为过,也许在我们还穿开裆裤的时候他们就开始编程了,哈哈…)写的函数都比较规范,那样 
\r\n我们就不必进行强制转换了。 
\r\n
\r\n2.3元素存取 
\r\n      我们可以使用下标操作符[]和函数at()对元素包含的字符进行访问。但是应该注意的是操作符[]并不检查索引是否有效(有效索引0~str.length()),如果索引失效,会引起未定义的行为。而at()会检查,如果使用 
\r\nat()的时候索引无效,会抛出out_of_range异常。 
\r\n有一个例外不得不说,const string 
\r\na;的操作符[]对索引值是a.length()仍然有效,其返回值是’ ’。其他的各种情况,a.length()索引都是无效的。举例如下: 
\r\nconst string Cstr("const string"); 
\r\nstring Str("string"); 
\r\n
\r\nStr[3]; //ok 
\r\nStr.at(3); //ok 
\r\n
\r\nStr[100]; //未定义的行为 
\r\nStr.at(100); //throw out_of_range 
\r\n
\r\nStr[Str.length()] //未定义行为 
\r\nCstr[Cstr.length()] //返回 ‘ ’ 
\r\nStr.at(Str.length());//throw out_of_range 
\r\nCstr.at(Cstr.length()) ////throw out_of_range 
\r\n
\r\n我不赞成类似于下面的引用或指针赋值: 
\r\nchar& r=s[2]; 
\r\nchar* p= &s[3]; 
\r\n因为一旦发生重新分配,r,p立即失效。避免的方法就是不使用。 
\r\n
\r\n2.4比较函数 
\r\n      C++字符串支持常见的比较操作符(>,>=,<,<=,==,!=),甚至支持string与C-string的比较(如 
\r\nstr<"hello")。在使用>,>=,<,<=这些操作符的时候是根据"当前字符特性"将字符按字典顺序进行逐一得 
\r\n比较。字典排序靠前的字符小,比较的顺序是从前向后比较,遇到不相等的字符就按这个位置上的两个字符的比较结果确定两个字符串的大小。同时,string 
\r\n("aaaa") <string(aaaaa)。 
\r\n另一个功能强大的比较函数是成员函数compare()。他支持多参数处理,支持用索引值和长度定位子串来进行比较。他返回一个整数来表示比较结果,返回值意义如下:0-相等 
\r\n〉0-大于 <0-小于。举例如下: 
\r\nstring s("abcd"); 
\r\n
\r\ns.compare("abcd"); //返回0 
\r\ns.compare("dcba"); //返回一个小于0的值 
\r\ns.compare("ab"); //返回大于0的值 
\r\n
\r\ns.compare(s); //相等 
\r\ns.compare(0,2,s,2,2); //用"ab"和"cd"进行比较 小于零 
\r\ns.compare(1,2,"bcx",2); //用"bc"和"bc"比较。 
\r\n怎么样?功能够全的吧!什么?还不能满足你的胃口?好吧,那等着,后面有更个性化的比较算法。先给个提示,使用的是STL的比较算法。什么?对STL一窍不通?靠,你重修吧! 
\r\n
\r\n
\r\n2.5 更改内容 
\r\n这在字符串的操作中占了很大一部分。 
\r\n
\r\n首先讲赋值,第一个赋值方法当然是使用操作符=,新值可以是string(如:s=ns) 
\r\n、c_string(如:s="gaint")甚至单一字符(如:s=’j’)。还可以使用成员函数assign(),这个成员函数可以使你更灵活的对字符串赋值。还是举例说明吧: 
\r\n
\r\ns.assign(str); //不说 
\r\ns.assign(str,1,3);//如果str是"iamangel" 就是把"ama"赋给字符串 
\r\ns.assign(str,2,string::npos);//把字符串str从索引值2开始到结尾赋给s 
\r\ns.assign("gaint"); //不说 
\r\ns.assign("nico",5);//把’n’ ‘I’ ‘c’ ‘o’ ‘ ’赋给字符串 
\r\ns.assign(5,’x’);//把五个x赋给字符串 
\r\n把字符串清空的方法有三个:s="";s.clear();s.erase();(我越来越觉得举例比说话让别人容易懂!)。 
\r\nstring提供了很多函数用于插入(insert)、删除(erase)、替换(replace)、增加字符。 
\r\n先说增加字符(这里说的增加是在尾巴上),函数有 +=、append()、push_back()。举例如下: 
\r\ns+=str;//加个字符串 
\r\ns+="my name is jiayp";//加个C字符串 
\r\ns+=’a’;//加个字符 
\r\n
\r\ns.append(str); 
\r\ns.append(str,1,3);//不解释了 同前面的函数参数assign的解释 
\r\ns.append(str,2,string::npos)//不解释了 
\r\n
\r\ns.append("my name is jiayp"); 
\r\ns.append("nico",5); 
\r\ns.append(5,’x’); 
\r\n
\r\ns.push_back(‘a’);//这个函数只能增加单个字符 对STL熟悉的理解起来很简单 
\r\n
\r\n      string中间的某个位置插入字符串,这时候你可以用insert()函数,这个函数需要你指定一个安插位置的索引,被插入的字符串将放在这个索引的后面。 
\r\n
\r\ns.insert(0,"my name"); 
\r\ns.insert(1,str); #p#分页标题#e#
\r\n      这种形式的insert()函数不支持传入单个字符,这时的单个字符必须写成字符串形式(让人恶心)。既然你觉得恶心,那就不得不继续读下面一段话:为了插 
\r\n入单个字符,insert()函数提供了两个对插入单个字符操作的重载函数:insert(size_type index,size_type num,chart 
\r\nc)和insert(iterator pos,size_type num,chart 
\r\nc)。其中size_type是无符号整数,iterator是char*,所以,你这么调用insert函数是不行的:insert(0,1, 
\r\n’j’);这时候第一个参数将转换成哪一个呢?所以你必须这么写:insert((string::size_type)0,1,’j’)!第二种形式指 
\r\n出了使用迭代器安插字符的形式,在后面会提及。顺便提一下,string有很多操作是使用STL的迭代器的,他也尽量做得和STL靠近。 
\r\n删除函数erase()的形式也有好几种(真烦!),替换函数replace()也有好几个。举例吧: 
\r\nstring s="il8n"; 
\r\ns.replace(1,2,"nternationalizatio");//从索引1开始的2个替换成后面的C_string 
\r\ns.erase(13);//从索引13开始往后全删除 
\r\ns.erase(7,5);//从索引7开始往后删5个 
\r\n
\r\n2.6提取子串和字符串连接 
\r\n题取子串的函数是:substr(),形式如下: 
\r\ns.substr();//返回s的全部内容 
\r\ns.substr(11);//从索引11往后的子串 
\r\ns.substr(5,6);//从索引5开始6个字符 
\r\n把两个字符串结合起来的函数是+。(谁不明白请致电120) 
\r\n
\r\n2.7输入输出操作 
\r\n1.>> 从输入流读取一个string。 
\r\n2.<< 把一个string写入输出流。 
\r\n另一个函数就是getline(),他从输入流读取一行内容,直到遇到分行符或到了文件尾。 
\r\n
\r\n2.8搜索与查找 
\r\n查找函数很多,功能也很强大,包括了: 
\r\nfind() 
\r\nrfind() 
\r\nfind_first_of() 
\r\nfind_last_of() 
\r\nfind_first_not_of() 
\r\nfind_last_not_of() 
\r\n      所有的函数的参数说明如下: 
\r\n第一个参数是被搜寻的对象。第二个参数(可有可无)指出string内的搜寻起点索引,第三个参数(可有可无)指出搜寻的字符个数。比较简单,不多说不理解的可以向我提出,我再仔细的解答。当然,更加强大的STL搜寻在后面会有提及。 
\r\n
\r\n      最后再说说npos的含义,string::npos的类型是string::size_type,所以,一旦需要把一个索引与npos相比,这个索引值必 须是string::size)type类型的,更多的情况下,我们可以直接把函数和npos进行比较(如:if(s.find("jia")== 
\r\nstring::npos))。 

\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2882, '2012-china-cup-competition-problems-six', '2012中国软件杯参赛题目(六)', '2012-08-30 19:15:48', '2019-03-25 21:29:22', 'Windows屏幕变化捕获和回放
\r\n项目简介
\r\n      Windows屏幕变化捕获是通过一种检测手段,检测出Windows操作系统屏幕在一定时间间隔以内发生变化的区域,并截取这些变化区域的屏幕图像,将图像数据保存到文件并同时发送到另一主机。屏幕变化回放就是按照固定的时间间隔连续地回放捕获到的变化区域的图像。
\r\n目前大多数VNC软件采用Mirror Driver技术捕获屏幕变化区域,但是对于采用DirectDraw绘制技术的软件引起的屏幕变化无法捕获。如UltraVNC,TigerVNC等。
\r\n      某些软件采用定时截取全屏幕图像再进行全像素比较的方法,能够精确计算出屏幕变化区域,但由于计算量大、消耗内存多导致性能严重下降。
\r\n还有一些软件由于会重复捕获变化区域产生数据冗余,导致存储或传输数据量过大。Splashtop Remote Desktop在苹果AppStore收费软件中下载量一度超过愤怒的小鸟,其PC端软件Splashtop Streamer凭借其出色的变化区域捕获性能取得了很大的成功。
\r\n
\r\n业务场景
\r\n      屏幕变化捕获与回放是远程桌面、VNC软件的核心技术之一,可以应用于下列场景:
\r\n1. 远程会议:会议主持人向所有参与者播放自己的屏幕,讲解会议内容。
\r\n2. 远程控制:大多数VNC软件都采用了这种技术。
\r\n3. 远程协助:应用于远程维护,例如QQ的远程协助。
\r\n4. 屏幕录制:可用于教育课件录制、软件操作演示。
\r\n5. 远程共享:包括桌面共享和应用程序共享。例如NetMeeting软件。
\r\n
\r\n功能性需求
\r\n1. 能够捕获到使用GDI技术绘制的屏幕变化。
\r\n2. 能够捕获到鼠标移动的屏幕变化。
\r\n3. 能够捕获到插入符闪烁引起的屏幕变化。
\r\n4. 成帧策略:按照固定的时间间隔将在该间隔内发生变化的所有区域进行合并,再剪裁掉冗余区域,最后构造成一帧。成帧间隔要小于等于33ms,即帧率大于等于30帧/秒。屏幕回放帧率与捕获帧率相同。
\r\n5. 帧压缩:对单个帧或连续帧进行压缩,允许采用成熟的压缩技术。
\r\n6. 帧存储:将压缩帧存入文件,回放时从文件读取帧。
\r\n7. 帧传输:将压缩帧传输到回放主机,回放时从网络读取帧。
\r\n8. 变化区域定义为一个矩形,而实际的变化形状是不规则的。这样,过大的矩形会导致帧数据量过多,最坏的情况是,矩形尺寸与屏幕尺寸相同;而过小的矩形会导致矩形数量过多。
\r\n9. 去除帧内冗余的变化区域。例如同一帧中,区域A和区域B存在交叠,则交叠部分的重复区域要去除。
\r\n10. 支持各种标准的屏幕分辨率,例如640*480,800*600,1024*768,1280*1024,1920*1080等,参考Windows控制面板中的屏幕分辨率设置中的几种设置。
\r\n11. 能够捕获到使用DirectDraw技术绘制的屏幕变化。
\r\n12. 能够捕获到使用OpenGL技术绘制的屏幕变化。
\r\n
\r\n非功能性需求
\r\n1. 软件运行分为2个独立进程,capture执行捕获过程,player执行回放过程。可以分别在不同的win32主机上运行。
\r\n2. 单独执行捕获过程,分辨率1024*768, 真彩色,从任务管理器观察CPU使用率不超过10%。(PC配置见“其他要求”)。
\r\n3. 单独执行回放过程,分辨率1024*768,真彩色,从任务管理器观察CPU使用率不超过10%。(PC配置见“其他要求”)。
\r\n4. 使用日志文件记载每个变化区域和所去除的冗余区域的屏幕坐标(x, y, width, height)、所属的帧编号,成帧时间和回放时间。
\r\n5. 单独执行捕获过程或回放过程,从任务管理器观察虚拟内存状况,曲线波动平稳,最大内存占用不超过10M。
\r\n其他限制条件
\r\n1. 能够运行于Windows XP,Windows server、Windows vista、Windows 7等Win32平台。
\r\n2. 语言c/c++,
\r\n3. 开发平台VC6/VS2003/VS2005/VS2008任选.
\r\n
\r\n测试用例
\r\n测试1:玩3D游戏(如魔兽争霸)的录制与回放
\r\n测试2:使用迅雷看看播放视频的屏幕录制与回放
\r\n测试3:自动播放PPT的屏幕录制与回放
\r\n测试4:用户操作IE上网过程的屏幕录制与回放
\r\n测试5:采用MS Office编辑文档过程的屏幕录制与回放
\r\n
\r\n其他要求
\r\n1.  测试1-5的回放要流畅、无马赛克、无停顿。
\r\n2.  测试4的鼠标移动回放平滑。
\r\n3.  测试5的插入符闪烁回放明显。
\r\n4.  PC最低配置:CPU 1.5Hz, 内存512M,磁盘40G,显卡支持直接写屏并带有GPU。
\r\n5.  允许利用GPU提高性能。
\r\n6.  在采集、回放的过程中定时统计帧率,写入日志。
\r\n
\r\n产品交付物
\r\n1.  可运行的测试软件,capture.exe执行捕获过程,player.exe执行回放过程,capture.exe能够在后台运行。
\r\n2.  设计文档,需要描述系统架构、捕获方法、压缩方案、矩形大小设定策略、传输方法、存储策略、冗余去除算法、回放渲染方案等。
\r\n3.  测试文档,需要描述测试策略,典型测试用例及其执行结果。
\r\n4.  性能测试数据和结果。
\r\n5.  源代码。

\r\n#p#副标题#e#
\r\n评分标准
\r\n1.  功能性需求的1-10和非功能性需求中的1-5,占45分,要求必须实现且满足其他要求1-3。少一项扣3分。
\r\n2.  功能性需求的11,占5分。
\r\n3.  功能性需求的12,占5分。
\r\n4.  产品交付物1-5各占2分,其中质量占1分,共10分。
\r\n5.  单独执行捕获过程,CPU平均消耗,以10%为基准,每降低一个百分点分别给1,2,3,4分,低于5%,给10分。
\r\n6.  单独执行捕获过程,CPU平均消耗,以10%为基准,每降低一个百分点分别给1,2,3,4分,低于5%,给10分。
\r\n7.  压缩比、采集数据量(含冗余去除算法)占15分,测试1-5采用同样的测试数据(3D软件、影片、PPT等)和测试时长,所保存的存储文件越小给分越多。
\r\n8.  捕获和回放平均帧率低于30帧/秒,每少一帧扣1分。(注意:从非功能需求4和其他要求6的日志判断)。
\r\n9.  实现了其他要求5,加2分。
\r\n10. 实现了其他要求6,加2分。

\r\n
\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2883, 'three-kingdoms-characters-long-jie-zhi-sun-quan', '三国杀人物详解之孙权', '2012-08-30 07:18:01', '2019-03-25 21:29:22', '

\r\n 三国杀孙权【吴国】
\r\n

\r\n

\r\n 武将名:孙权

\r\n

\r\n 称号:年轻的贤君

\r\n

\r\n 势力:吴国

\r\n

\r\n 生命:★★★★

\r\n

\r\n 武将技:

\r\n

\r\n 制衡:出牌阶段,你可以弃掉任意数量的牌,然后摸取等量的牌.每回合限用一次。

\r\n

\r\n 救援:主公技,锁定技,其他吴势力角色在你濒死状态下对你使用【桃】时,你额外回复1点体力。

\r\n

\r\n [Q]孙权发动【制衡】时,是否可以弃置其装备区里的牌?

\r\n

\r\n [A]可以。

\r\n

\r\n [Q]“吴”势力角色是否可以在孙权非濒死时对他使用【桃】?

\r\n

\r\n [A]不可以。

\r\n

\r\n [Q]孙权进入濒死状态时自己使用【桃】,回复几点体力值?

\r\n

\r\n [A]1点。

\r\n

\r\n 例如:孙权的剩余体力为1点,受到【闪电】造成的3点伤害,此时孙尚香对孙权使用了1张【桃】,陆逊又对孙权使用了1张【桃】,则孙权回复至2点体力(1-3+2+2=2)。

\r\n

\r\n [Q]孙权进入濒死状态时,吴将能否对其使用【酒】?

\r\n

\r\n [A]不能。

\r\n

\r\n [Q]孙权能否先重铸【铁索连环】再制衡掉重铸得到的牌?

\r\n

\r\n [A]可以。

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2884, 'mouse-effects', '鼠标移动效果', '2012-08-21 05:13:27', '2019-03-25 21:29:22', '\r\n \r\n\r\n注意:此代码仅适用于IE。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2885, 'js-star-eval', 'JS星级评分', '2012-08-20 19:29:12', '2019-03-25 21:29:22', '\r\n ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2886, 'js-form-state', 'JS表单效果', '2012-08-20 19:20:25', '2019-03-25 21:29:22', '\r\n ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2887, 'js-open-light', 'JS开灯关灯', '2012-08-20 19:07:38', '2019-03-25 21:29:22', '点击下方按钮运行:\r\n\r\n ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2888, 'mouse-hover-effects', '鼠标悬浮效果', '2012-08-20 18:18:59', '2019-03-25 21:29:22', '代码如下:\r\n\r\n\r\n\r\n\r\n\r\n\r\n
\r\n
<html>\r\n<head>\r\n    <title></title>\r\n</head>\r\n<body>\r\n<a href=\"http://www.xinvalue.com\" target=\"_blank\" onmouseout=\"document.getElementById(\'XinDiv\').style.display=\'none\'\" onmouseover=\"document.getElementById(\'XinDiv\').style.display=\'\'\" >新价值网</a>\r\n<div id=\"XinDiv\" style=\"display:none;border-color:Green;border-style:dotted;border-width:1px;\">\r\n新价值网:由唐有炜创立于2012年8月18日,致力于编程技术交流、软件源码共享、网站设计开发。\r\n</div>\r\n</body>\r\n</html>
\r\n
\r\n点击下方按钮运行:\r\n\r\n ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2889, 'js-control-the-display-of-layers', 'JS控制层的显示', '2012-08-20 06:56:36', '2019-03-25 21:29:22', '\r\n\r\n\r\n\r\n\r\n\r\n
\r\n
<html>\r\n<head>\r\n    <title></title>\r\n    <script type=\"text/javascript\">\r\n        function togDiv(cb)\r\n        {\r\n            var div1 = document.getElementById(\"div1\");\r\n            if (cb.checked)\r\n            {\r\n                div1.style.display = \'\';//Display没有值是显示,none不显示\r\n            }\r\n            else\r\n            {\r\n                div1.style.display = \'none\';\r\n            }\r\n    }\r\n    </script>\r\n</head>\r\n<body>\r\n<input type=\"checkbox\" id=\"cbShow\" onclick=\"togDiv(this)\"> <label for=\"cbShow\">显示高级选项</label>\r\n<div id=\"div1\" style=\"display:none\">这里是高级选项</div>\r\n</body>\r\n</html>\r\n
\r\n
\r\n点击下方按钮运行:\r\n\r\n ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2890, 'a-beautiful-js-date', '一款漂亮的JS时间日期选择器', '2013-02-03 14:00:00', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

由于calendar.js行数较多放在附件中,请在下方点击下载:

测试代码:

  1. <html> 
  2. <title>JS时间选择</title> 
  3. <script type="text/javascript" src="Calendar.js"></script> 
  4. <body> 
  5. JS时间选择:<input type="text"  onfocus="new Calendar().show(this)" > 
  6. </body> 
  7. </html> 

界面演示:

\"2013-11-20_225448\"

在线演示:

http://sandbox.runjs.cn/show/7narvb3v

下载地址一:

\"bdyun\" 

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2891, 'a-programmer-to-learn-younger-brother-sister-school-recommendations', '一个程序员对学弟学妹建议', '2012-08-18 23:56:27', '2019-03-25 21:29:22', '      始终认为,对一个初学者来说,IT界的技术风潮是不可追赶的。我时常看见自己的DDMM们把课本扔了,去买些价格不菲的诸如C#, VB.Net 这样的大部头,这让我感到非常痛心。而许多搞不清指针是咋回事的BBS站友眉飞色舞的讨论C#里面可以不用指针等等则让我觉得好笑。C#就象当年的ASP 一样,“忽如一夜春风来,千树万树梨花开”,结果许多学校的信息学院成了“Web 学院”。96, 97级的不少大学生都去做Web了。当然我没有任何歧视某一行业的意识。我只是觉得如果他们把追赶这些时髦技术的时间多花一点在基础的课程上应该是可以走得更远的。\r\n\r\n几个误区\r\n\r\n      初学者对C#风潮的追赶其实也只是学习过程中经常遇到的几个误区之一。我将用一些实际的例子来说明这些现象,你可以按部就班的看看自己是不是属于其中的一种或者几种:\r\n\r\n认为计算机技术等于编程技术:\r\n\r\n      有些人即使没有这个想法,在潜意识中也有这样的冲动。让我奇怪的是,许多信息学院的学生也有这样的念头。认为计算机专业就是编程专业,与编程无关的,或者不太相关课程他统统都不管,极端的学生只要书上没带“编程”两个字他就不看。\r\n\r\n      其实编程只是计算机技术应用过程中一种复杂性最低的劳动,这就是为什么IT业最底层的人是程序员(CODER)。计算机技术包括了多媒体,计算机网络,人 工智能,模式识别,管理信息系统等等这些方面。编程工作只是在这些具体技术在理论研究或者工程实践的过程中表达算法的过程。编程的人不一定对计算机技术的了解就一定很高。而一个有趣的现象是,不少大师级的计算机技术研究者是不懂编程的。网上的炒作和现实中良好的工作待遇把编程这种劳动神秘化了。其实每一个 程序员心里都明白,自己这些东西,学的时候并不比其它专业难,所以自然也不会高档到哪里去。\r\n\r\n咬文嚼字的孔已己作风:\r\n\r\n      我见过一本女生的《计算机网络原理》教材,这个女生像小学生一样在书上划满了横杠杠,笔记做得满满的,打印出来一定比教材还厚。我不明白的是,像计算机网 络原理这样的课程有必要做笔记?我们的应试教育的确害了不少学生,在上《原理》这一类课程的时候许多学生像学《马列原理》一样逐字背诵记忆。这乃是我见过 的最愚蠢的行为。所谓《原理》,即是需要掌握它为什么这样做,学习why,而不是how(怎样做)。极端认真的学生背下以太网的网线最大长度,数据帧的长度,每个字段的意义,IP报头的格式等等,但是忘了路由的原则,忘了TCP/IP协议设计的宗旨。总之许多人花了大量的时间把书背得滚瓜烂熟却等于什么也 没学。\r\n\r\n      在学习编程的时候这些学生也是这样,他们确切的记得C++语法的各个细节。看完了C++ 教程后看《Thinking in C++》(确实是好书),《Inside C++》,《C++ reference》,this C++, that C++……,然后是网上各种各样的关于C++语法的奇闻逸事,然后发现自己又忘了C++的一些语法,最后回头继续恶补…。有个师弟就跟我说:“C++太难了,学了这里忘了那里,学了继承忘了模板。”我的回答道:“你不去学就容易了”。我并没有教坏他,只是告诉他,死抠C++的语法就和孔已己炫耀茴香豆的茴字有几种写法一样毫无意义。你根本不需要对的C++语法太关心,动手编程就是了,有不记得的地方一查MSDN就立马搞定。我有个结论就是,实际的开发过程中对程序语法的了解是最微不足道的知识。这是为什么我在为同学用Basic(我以前从没有学过它)写一个小程序的时候,只花了半个小时看了看语法,然后再 用半个小时完成了程序,而一个小时后我又完全忘记了Basic 的所有关键字。\r\n\r\n不顾基础,盲目追赶时髦技术:\r\n\r\n      终于点到题目上来了。大多数的人都希望自己的东西能够马上跑起来,变成钱。这种想法对一个已经进入职业领域的程序员或者项目经理来说是合理的,而且IT技术进步是如此的快,不跟进就是失业。但是对于初学者来说(尤其是时间充裕的大中专在校生),这种想法是另人费解的。一个并未进入到行业竞争中来的初学者最大的资本便是他有足够的时间沉下心来学习基础性的东西,学习why而不是how。时髦的技术往往容易掌握,而且越来越容易掌握,这是商业利益的驱使,为了最大化的降低软件开发的成本。但在IT领域内的现实就是这样,越容易掌握的东西,学习的人越多,而且淘汰得越快。每一次新的技术出来,都有许多初学者跟进,这些初学者由于缺乏必要的基础而使得自己在跟进的过程中花费大量的时间,而等他学会了,这种技术也快淘汰了。基础的课程,比方数据结构,操作系统原理等等虽然不能让你立马就实现一个Linux(这是许多人嘲笑理论课程无用的原因),但它们能够显著的减少你在学习新技术时学习曲线的坡度。而且对于许多关 键的技术(比方Win32 SDK 程序的设计,DDK的编程)来说甚至是不可或缺的。\r\n\r\n      一个活生生的例子是我和我的一个同学,在大一时我还找不到开机按纽,他已经会写些简单的汇编程序了。我把大二的所有时间花在了汇编,计算机体系结构,数据结构,操作系统原理等等这些课程的学习上,而他则开始学习HTML和VB,并追赶ASP的潮流。大三的时候我开始学习Windows 操作系统原理,学习SDK编程,时间是漫长的,这时我才能够用VC开发出象模象样的应用程序。我曾一度因为同学的程序已经能够运行而自己还在学习如何创建对话框而懊恼不已,但临到毕业才发现自己的选择是何等的正确。和我谈判的公司开出的薪水是他的两倍还多。下面有一个不很恰当的比方:假设学习VB编程需要 4个月,学习基础课程和VC的程序设计需要1年。那么如果你先学VB,再来学习后者,时间不会减少,还是1年,而反过来,如果先学习后者,再来学VB,也许你只需要1个星期就能学得非常熟练。\r\n#p#第二页#e#\r\n几个重要的基础课程\r\n\r\n      如果你是学生,或者如果你有充足的时间。我建议你仔细的掌握下面的知识。我的建议是针对那些希望在IT技术上有所成就的初学者。同时我还列出了一些书目,这些书应该都还可以在书店买到。说实在的,我在读其他人的文章时最大的心愿就是希望作者列出一个书单。\r\n\r\n大学英语 -不要觉得好笑。我极力推荐这门课程是因为没有专业文档的阅读能力是不可想象的。中文的翻译往往在猴年马月才会出来,而现在的许多出版社干脆就直接把E文印刷上去。学习的方法是强迫自己看原版的教材,开始会看不懂,用多了自然熟练。吃得苦下得狠心绝对是任何行业都需要的品质。\r\n\r\n计算机体系结构和汇编语言 -关于体系结构的书遍地都是,而且也大同小异,倒是汇编有一本非常好的书《80x86汇编语言程序设计教程》(清华大学出版社,黑色封面,杨季文著)。你需要着重学习386后保护模式的程序设计。否则你在学习现代操作系统底层的一些东西的时候会觉得是在看天书。\r\n\r\n计算机操作系统原理我们的开发总是在特定的操作系统上进行,如果不是,只有一种可能:你在自己实现一个操作系统。无论如何,操作系统原理是必读的。这就象我们为一个芯片制作外围设备时,芯片基本的工作时序是必需了解的。这一类书也很多,我没有发现哪一本书非常出众。只是觉得在看完了这些书后如果有空就应该看看 《Inside Windows 2000》(微软出版社,我看的是E文版的,中文的书名想必是Windows 2000 技术内幕之类吧)。关于学习它的必要性,ZDNET上的另一篇文章已经有过论述。\r\n\r\n数据结构和算法 这门课程能够决定一个人程序设计水平的高低,是一门核心课程。我首选的是清华版的(朱战 立,刘天时)。很多人喜欢买C++版的,但我觉得没有必要。C++的语法让算法实现过程变得复杂多了,而且许多老师喜欢用模块这一东西让算法变得更复杂。 倒是在学完了C版的书以后再来浏览一下 C++的版的书是最好的。\r\n\r\n软件工程 这门课程是越到后来就越发现它的重要,虽然刚开始看时就象看马哲一样不知所云。我的建议是看《实用软件工程》(黄色,清华)。不要花太多的时间去记条条框框,看不懂就跳过去。在每次自己完成了一个软件设计任务(不管是练习还是工作)以后再来回顾回顾,每次都会有收获。\r\n\r\nWindows 程序设计 -《北京大学出版社,Petzold著》我建议任何企图设计Windows 程序的人在学习VC以前仔细的学完它。而且前面的那本《Inside Windows 2000》也最好放到这本书的后面读。在这本书中,没有C++,没有GUI,没有控件。有的就是如何用原始的C语言来完成Windows 程序设计。在学完了它以后,你才会发现VC其实是很容易学的。千万不要在没有看完这本书以前提前学习VC,你最好碰都不要碰。我知道的许多名校甚至都已经用它作为教材进行授课。可见其重要。\r\n\r\n上面的几门课程我认为是必学的重要课程(如果你想做Windows 程序员)。\r\n\r\n      对于其它的课程有这样简单的选择方法:如果你是计算机系的,请学好你所有的专业基础课。如果不是,请参照计算机系的课程表。如果你发现自己看一本书时无法 看下去了,请翻到书的最后,看看它的参考文献,找到它们并学习它们,再回头看这本书。如果一本书的书名中带有“原理”两个字,你一定不要去记忆它其中的细节,你应该以一天至少50页的速度掌握其要领。尽可能多的在计算机上实践一种理论或者算法。\r\n\r\n日三省乎己 \r\n\r\n      每天读的书太多,容易让人迷失方向。一定要在每天晚上想想自己学了些什么,还有些什么相关的东西需要掌握,自己对什么最感兴趣,在一本书上花的时间太长还是不够等等。同时也应该多想想未来最有可能出现的应用,这样能够让你不是追赶技术潮流而是引领技术潮流。同时,努力使用现在已经掌握的技术和理论去制作具有一定新意的东西。坚持这样做能够让你真正成为一个软件“研发者”而不仅仅是一个CODER。\r\n\r\n把最多的时间花在学习上\r\n\r\n      这是对初学者最后的忠告。把每个星期玩CS或者CS的时间压缩到最少,不玩它们是最好的。同时,如果你的ASP技术已经能够来钱,甚至有公司请你兼职的 话,这就证明你的天分能够保证你在努力的学习之后取得更好的收益,你应该去做更复杂的东西。眼光放长远一些,这无论是对谁都是适用的。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2892, 'instructions-to-install-in-ubuntu-lamp', 'ubuntu中一行指令安装LAMP', '2012-08-16 18:56:42', '2019-03-25 21:29:22', 'sudo apt-get install lamp-server^\r\n\r\n由于LAMP大部分操作与/var/www目录相关,为了方便,修改该目录的权限为普通用户可访问。\r\n\r\nsudo chmod 777 /var/www/\r\n\r\n注意:安装到MySQL时,会提示输入管理员密码,并且两次密码必须相同。\r\n\"\"\r\n\r\n安装完成后,打开看浏览器,输入http://localhost/,如果出现It works!说明初步安装成功!\r\n\"\"\r\n\r\n接下来测试一下PHP,在/var/www/目录下建立一个文件,命名为lamp.php,打开该文件输入\r\n<?php\r\nphpinf0();\r\n?>\r\n关闭保存。\r\n打开浏览器,输入:http://localhost/lamp.php,如果出现一下画面,则PHP安装成功并且与Apache已经结合。\r\n\"\"\r\n#p#副标题#e#\r\n\r\n安装PhpMyAdmin:\r\nsudo apt-get install phpmyadmin\r\n注意:\r\n在安装过程中会要求选择Web server:apache2或lighttpd,选择apache2(因为笔者对Apache更熟悉),按tab键然后确定。然后会要求输入设置的Mysql数据库密码连接密码 Password of the database\'s administrative user。\r\n\"\"\r\n\r\n然后将phpmyadmin与apache2建立连接,以我的为例:www目录在/var/www,phpmyadmin在/usr/share /phpmyadmin目录,所以就用命令:\r\nsudo ln -s /usr/share/phpmyadmin /var/www\r\n建立连接。       \r\nphpmyadmin测试:在浏览器地址栏中打开http://localhost/phpmyadmin。\"\"', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2893, 'mysql-garbled-data-import-and-export-solutions', 'MySql数据导入导出乱码解决方案', '2012-08-16 05:11:17', '2019-03-25 21:29:22', '
在工作中遇到使用命令的方式导出和导入数据库时会出现乱码的情况,根据笔者经验,现提供以下方案供参考。\r\n具体情况如下:
\r\n
我使用windows作为导出数据源,并导入 freebsd环境下的mysql库中
\r\n
\r\n\r\n导出数据:\r\n\r\nmysql> select * from table into outfile ‘c:table.txt’ where 条件\r\n(或selet * into outfile from table where 条件 )\r\n\r\n导出来的数据使用windows记事本打开会出现中文乱码情况。\r\n\r\n同时使用导入数据的命令:\r\nmysql>load data local infile ‘c:\\table.txt’ into table `table`\r\n\r\n插入的数据也会出现乱码情况。\r\n\r\n在查阅资料后发现,这是mysql服务器系统变量中的character_set_database中默认的字符集问题。\r\n\r\n详情参见: mysql5.1中文手册 13.2.5. LOAD DATA INFILE语法\r\n\r\n……\r\n由character_set_database系统变量指示的字符集被用于解释文件中的信息。SET NAMES\r\n\r\n和character_set_client的设置不会影响对输入的解释。\r\n\r\n……\r\n\r\n我的解决方法:\r\n\r\n导出数据\r\n\r\n一、首先在windows平台下mysql用作导出数据库源。查看字符编码的系统变量:\r\nmysql> show variables like ‘%char%’;\r\n\r\n+————————–+—————————-+\r\n| Variable_name | Value |\r\n+————————–+—————————-+\r\n| character_set_client | latin1 |\r\n| character_set_connection | latin1 |\r\n| character_set_database | latin1 |\r\n| character_set_filesystem | binary |\r\n| character_set_results | latin1 |\r\n| character_set_server | gbk |\r\n| character_set_system | utf8 |\r\n| character_sets_dir | D:mysqlsharecharsets |\r\n+————————–+—————————-+\r\n查看character_set_database,这里是latin1,latin1是装不了多字节字符集的\r\n\r\n二、在windows下设置系统变量为utf8\r\n\r\nmysql>set character_set_database=utf8; ##设置默认的字符集为utf8\r\n\r\n三、导出数据\r\n\r\nmysql> select * from table into outfile ‘c:table.txt’ where +条件\r\n\r\n这时导出了我想要的部分数据,并以txt文件存在 table.txt中。\r\n\r\n导入数据\r\n\r\n在freebsd平台下\r\n\r\n一、同样设置字符编码的系统变量\r\nmysql> show variables like ‘%char%’;\r\n\r\n+————————–+—————————-+\r\n| Variable_name | Value |\r\n+————————–+—————————-+\r\n| character_set_client | latin1 |\r\n| character_set_connection | latin1 |\r\n| character_set_database | latin1 |\r\n| character_set_filesystem | binary |\r\n| character_set_results | latin1 |\r\n| character_set_server | gbk |\r\n| character_set_system | utf8 |\r\n|\r\n+————————–+—————————-+\r\n\r\nmysql>set character_set_database=utf8; ##设置默认的字符集为utf8\r\n\r\n二、转载数据\r\n\r\nmysql>load data local infile ‘/home/table.txt’ into table `table`;\r\n\r\n
\r\n
至此、条件数据完整导入导出,并处理了乱码的情况
\r\n
总之,两台mysql服务器导入导出时,一定要确保两台服务器的character_set_database参数相同,这样才能防止一些 乱码的情况。当然我们还可以使用其他字符集,如gbk来进行调整。视情况操作了。
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2895, 'intellij-idea-out-print-errors-built-web-projects-in-the-solution', 'Intellij Idea中建web项目out.print报错解决方案', '2012-08-16 05:02:51', '2019-03-25 21:29:22', '\"\"\r\n用IntelJ Idea创建Jsp项目,输入out.print(\"\");时print竟然是红色,这就不可思议了。\r\n\r\n后来,在一个英文网站找到了解决方案。(参考自http://stackoverflow.com/questions/3914139/intellij-9-unable-to-recognize-implicit-object-methods-in-jsps)\r\n在IntelJ Idea上点击File -> Project structure -> Modules -> Dependencies -> Add,找到Tomcat的lib目录下的jsp-api.jar和servlet-api.jar,将他们添加进去:\r\n\"\"\r\n问题解决,此后再写out.print(\"\");就不会报错了。\r\n\"\"', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2896, 'sql-server-2008-configuration-manager-is-unable-to-open', 'Sql Server 2008配置管理器无法打开...', '2012-08-16 05:02:29', '2019-03-25 21:29:22', '      打开sql server 2008的配置管理器出现以下错误:\r\n\r\n\"\"\r\n(上面是:无法连接到WMI提供程序。您没有权限或者该服务器无法访问。请注意,您只能使用SQL Server配置管理器管理SQL Server 2005 和更高版本的服务器。找不到指定的模块。[0×8007007e])。困扰许久,终于找到了解决方案。\r\n\r\n     \r\n\r\n修复步骤一、\r\n这里的WMI应该是“Windows Management Instrumentation”,进服务管理,看下这个服务是否已启动。打开服务的方法:\r\n1、我的电脑右键->管理->服务\r\n2、控制面板->管理工具->服务\r\n3、直接在开始菜单->运行,输入 services.msc /s      回车。\r\n\r\n修复步骤二、\r\n开始->运行Cmd.exe进命令行\r\n进入MSSQL2008安装目录cd Program FilesMicrosoft SQL Server100Shared\r\n输入 mofcomp \"C:Program FilesMicrosoft SQL Server100Sharedsqlmgmproviderxpsp2up.mof\"\r\n注意:Sql Server 2008目录中是100,2005是90,不要弄错了,我之前就弄错了,郁闷了好久。\r\n//具体的路径要看你SQL的安装路径了,我这里是默认的。\r\n\r\n执行结果如下:\r\n\r\n\"\"\r\n如果显示类似这样的就说明成功了。此时就可以正常打开了! ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2897, 'completely-disables-the-vs-debugger', '彻底禁用vs及时调试器', '2012-08-16 04:46:10', '2019-03-25 21:29:22', '
\r\n

彻底禁用VS2008及时调试器:\r\n把以下文件改个名就可以啦。(想恢复时再把名字改归去。)\r\nC:WINDOWSsystem32vsjitdebugger.exe

\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2898, 'cup-competition-the-topic-of-2012-china-software-v', '2012中国软件杯参赛题目(五)', '2012-08-16 04:43:42', '2019-03-25 21:29:22', '\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
基于安卓的移动应用开发
赛题简介:介绍整个赛题的思路和整体要求 开发一个基于Android平台的手机相册软件。该软件可以拍摄、编辑、查看、分享本地相册以及网络相册;
赛题业务场景:描述赛题相关的真实企业业务背景。从真实场景中,适当简化或者提炼出适合比赛的赛题场景业务模型可以参考人人网的网络相册,提供在线浏览、下载、编辑、上传照片等功能,也可即时分享照片到另外一个SNS社区(新浪微博、腾讯微博等)。
\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
功能性需求
\r\n
1、具有拍摄、编辑、查看、共享及分发的功能;\r\n2、连接SNS网络时使用客户端模式,禁止使用Browser或者WebView等借助网页页面的方式;\r\n3、分享SNS社区可以从新浪微博、网易微博、腾讯微博中选择一个或多个,也可以在此范围之外选择;\r\n4、能够绑定SNS社区账户,第一次访问需要授权及认证,以后便可直接访问;\r\n5、具有换肤功能,提供换肤模板库供用户选择;\r\n6、网络异常时能够提示或禁止相关网络相册功能;\r\n7、自动切换3G、WIFI等网络通道,优先使用WIFI。
\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
非功能性需求
\r\n
1、实际并发用户数不低于50个;\r\n2、平均事务响应时间小于等于10秒;\r\n3、平均服务响应时间小于等于5秒;\r\n4、文件传输不大于4MB;\r\n5、虚拟并发用户数100~300之间。
其他限制条件:开发环境、实验平台、开发语言、数据库、编译器等限制条件开发环境:Android SDK2.2、ADT、Windows Mobile5.0\r\n开发平台:ECLIPS或VisualStudio2010以上\r\n开发语言:J2MENET CompactFrameworkHTML+JSPHP\r\n数据库:mySQLSQLite
测试数据或平台:提供给参赛者的测试环境和测试数据。(可提供电子档) 测试平台:ADT(Android Development Tools)、Activity、Intent、Service、ContentProvicer\r\n\r\n测试数据:可在人人网上模拟操作,记录测试数据或从ContentProvider中获取
\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
其他要求
\r\n
文档要求:概要设计说明书(描述软件系统架构、逻辑架构、物理架构、部署结构、功能架构及关键技术,关键业务模块需通过UML图(用例图、时序图、状态图、包图、主要类图等)进行详细描述)、需求规格说明书(包括功能设计、非功能性设计、系统用例);\r\n\r\n测试要求:需进行单元测试,提供单元测试用例,单元测试覆盖率不低于90%;提供性能测试文档(包括测试脚本、实际吞吐率、阀值等);
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2899, '2012-cup-competition-of-china-software-topics-d', '2012中国软件杯参赛题目(四)', '2012-08-16 04:43:24', '2019-04-02 13:35:50', '\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
 基于Web的3D智能虚拟人
赛题简介:介绍整个赛题的思路和整体要求 基于Web的3D智能虚拟人
\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
赛题业务场景:描述赛题相关的真实企业业务背景。从真实场景中,适当简化或者提炼出适合比赛的赛题场景
\r\n
项目背景\r\n随 着互联网和软件的不断发展和对人们工作和生活的不断渗透,越来越多的及时交互工具和平台正在被大家广泛使用,其中也产生了对各种智能交互系统的需求,在工 作和生活中的各种信息查询、检索和信息分析和指导、以及智能辅助和决策系统中,智能虚拟人就是一种很好的方式来实现和满足这样的需求。\r\n如想在网络世界里进行完美的重现,通过第一、第三人称视角进行展览参观、交互,让用户达到“沉浸-交互-构想”的完美境界。另外搭建极富创意的WEB-3D虚拟展厅,是现代发展的一种新的展示平台,也是展现形式的一种新的突破。\r\n因此充分发挥网络的没有时空限制、受众广泛、数据信息量大,可以采取完全个性化的3D表现方式,将数字展览融入到3D虚拟社区的架构上,使得虚拟社区能像真实环境一样有效、有趣。
\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
功能性需求
\r\n
基本要求\r\n1.  采用web版形式展现\r\n2.  至少一个的3D智能虚拟人及其他辅助场景(辅助场景自由发挥)。\r\n3.  可以与用户简单对话,并根据语音指令或文字指令做各种操作,如播报新闻、天气、星座、农历、时间和日期等资讯.\r\n4.  3D智能虚拟人能根据问题的内容做出相应的表情和动作,如微笑、平静、委屈、摆手、挥手、点头、摇头等一般人类的表情和动作。\r\n5.  3D智能虚拟人可以代替无法24小时在线的现实人,可以实现自动搜寻,自动交友等功能,具有初步智能。
\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
非功能性需求
\r\n
\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
其他限制条件:开发环境、实验平台、开发语言、数据库、编译器等限制条件
\r\n
开发要求\r\n1、开发语言采用Java EE+MySql架构或ASP.Net+MSSqlServer架构\r\n2、可以充分采用VRML 3.0(X3D),DotMSN等技术,但不仅限与此。\r\n开发工具\r\n自定\r\n开发周期\r\n3个月\r\n交付成果物\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
递交物描述
需求规格说明书背景、功能概述、系统边界、和其他系统的关系、系统的运行环境要求等描述;
详细设计说明书对系统的详细设计
测试文档包含测试方案、测试用户、最终测试报告;
用户使用手册含操作手册、部署配置手册;
可运行的应用用于发布的应用及相应的配置文件;
源代码符合规范的程序源代码及数据库备份的打包
\r\n
\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
测试数据或平台:提供给参赛者的测试环境和测试数据。(可提供电子档)
\r\n
参考技术:\r\nVRML (Virtual Reality Modeling Language)\r\nVRML (Virtual Reality Modeling Language)是在Internet上营造虚拟环境的技术。它在Web网上创建可导航的、超链接的三维虚拟现实空间。\r\nVRML(Virtual Reality Modeling Language)即虚拟现实建模语言。是一种用于建立真实世界的场景模型或人们虚构的三维世界的场景建模语言,也具有平台无关性。是目前Internet上基于WWW的三维互动网站制作的主流语言。VRML是虚拟现实造型语言(Virtual Reality Modeling Language)的简称,本质上是一种面向web,面向对象的三维造型语言,而且它是一种解释性语言。VRML的对象称为结点,子结点的集合可以构成复杂的景物。结点可以通过实例得到复用,对它们赋以名字,进行定义后,即可建立动态的VR(虚拟世界)。\r\nDotMSN\r\ndotmsn是一个提供与MSN Messenger Service连通的开源的独立类库.类库是使用C #建立的,因此,可以很好的支持.Net环境中的各种语言dotmsn的应用范围很广,包括创建MSN机器人,可以创建自定义的客户端。方便地与MSN Messenger Service进行通信。
\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
评分标准
\r\n
综合满分150分\r\n基本分满分:满分100分\r\n
    \r\n
  • 构建出3D的虚拟人,并能在web上运动和显示。0-10分。
  • \r\n
  • 构建出辅助场景,并符合题意要求。0-10分。
  • \r\n
  • 提交成果物齐全,并符合要求。0-10分。
  • \r\n
  • 可以与用户简单对话,并根据语音指令或文字指令做各种操作。0-40分。
  • \r\n
  • 能根据问题的内容做出相应的表情和动作。0-10分。
  • \r\n
  • 采用规定的技术要求和技术架构。0-10分。
  • \r\n
  • 题意新颖,有较强的实用性和交互性。0-10分。
  • \r\n
\r\n提高分加分:满分20分\r\n
    \r\n
  • 更完美地实现虚拟形象的逼真性;
  • \r\n
  • 表情、动作的真实性: 交流时语音与表情、口型匹配及身体其他动作的配合程度更高;
  • \r\n
  • 可以创建超过2个虚拟人,用户可以根据自己的喜好选择形象
  • \r\n
  • 可以具备成长能力
  • \r\n
\r\n评委印象分:满分30分
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2900, 'cup-competition-the-topic-of-2012-china-software-c', '2012中国软件杯参赛题目(三)', '2012-08-16 04:43:14', '2019-03-25 21:29:22', '\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
数字分配策略
\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
赛题简介:介绍整个赛题的思路和整体要求
\r\n
最优数字分配策略\r\n比赛题目条件:\r\n假设有2500个数据存储单元,形成为50*50的正方形矩阵。每个数据存储单元允许存储2~5个整数,整数范围为1~30,每个整数使用次数不限。\r\n\r\n50*50数据存储单元如下表形式:\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
1-11-21-31-4
2-12-22-32-4
3-13-23-33-4
4-14-24-34-4
\r\n其中1-1、1-2等表示存储单元在矩阵中的行列位置,也可以将其作为存储单元的名称。\r\n\r\n比赛题目要求:\r\n
    \r\n
  • 将1~30的整数按各存储单元的整数个数要求,分配到各数据存储单元中。未按要求分配整数,比赛无成绩,直接出局;
  • \r\n
  • 每个存储单元内的整数不能相同且不能相邻。如:1和2、2和2、2和3不能出现在同一个存储单元中。如果违反规则,按下述罚则处理:针对每个存储单元都统计一遍,出现一次相同,结果累加100违约分;出现一次相邻,结果累加50违约分;
  • \r\n
  • 每个存储单元与相邻的存储单元内的整数不能相同且不能相邻。如:第2-2存储单元内的整数与第1-1、1-2、1-3、2-1、2-3、3-1、3-2、3-3存储单元内的整数不能相同且不能相邻。如果违反规则,按下述罚则处理:针对每个存储单元都统计一遍,出现一次相同,结果累加20违约分;出现一次相邻,结果累加10违约分;
  • \r\n
  • 每个存储单元与相邻存储单元的相邻存储单元内的整数不能相同。如:第2-2存储单元内的整数与第1-4、2-4、3-4、4-1、4-2、4-3、4-4存储单元内的整数不能相同。如果违反规则,按下述罚则处理:针对每个存储单元都统计一遍,出现一次相同,结果累加1违约分;
  • \r\n
  • 各比赛小组自己设计分配算法,在规定时间内(比如1小时)运算分配结果,哪个小组最后的违约分值最低,哪个小组获胜。
  • \r\n
\r\n违约分计算举例:\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
行列列1列2
行11,3,57,9
行211,12,131,4
\r\n上表所示为部分存储单元内整数分配结果,违约值计算方法如下:\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
当前存储单元标识冲突存储单元标识当前存储单元违规整数冲突存储单元违规整数违约分数
1-12-21120
1-12-23410
1-12-25410
2-21-11120
2-21-14310
2-21-14510
2-12-1111250
2-12-1121350
\r\n为了方便计算,同存储单元内(如2-1)的冲突整数按照规则计算一次违约分,相邻存储单元内(如1-1和2-2)的冲突整数由于参照主体改变会重复计算违约分。最后的总分为所有违约分的总和。\r\n\r\n评价标准:\r\n本题没有标准答案,完全以运行时间和最后的违约值来评价比赛结 果。评审组将随机确定各数据存储单元内的整数个数,分别运行各比赛小组提交的程序,并将各程序在规定的比赛时间内运算的有效分配结果进行违约值统计,然后 按违约值由低到高排序,根据违约值排序产生结果排名(如果违约值相同,则用时少的小组排名靠前;违约值相同并且用时相同的小组排名相同)。
\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
赛题业务场景:描述赛题相关的真实企业业务背景。从真实场景中,适当简化或者提炼出适合比赛的赛题场景
\r\n
在移动通信过程中,移动用户的通信内容通过移动台(手机等移动通信设备)转换成频率信号后和通信基站(专门负责收发无线信号的物理通信设备)之间进行交互传输。\r\n国家相关部门为各电信运营商划定专门的频率区间,此频率区间按照相关电信标准可平均划分若干等份小的频率区间作为信号传输的最小单位,每个最小单位最多可同时为8个移动用户服务。各电信运营商频率区间不一样,频率带宽也不一样,即可划分的最小单位个数也不一样。\r\n因此,各电信运营商需要根据用户密度在有限的频率资源条件下,建立多个通信基站,每个通信基站分配1个或多个服务频率,以服务通信区域内的用户群。同时,如果基站内或邻近的基站使用相同或相近的频率收发信号,这些基站由于距离位置关系,会相互产生不同程度的电磁干扰,导致基站服务的移动用户出现不同程度的通信障碍。\r\n因此,各电信运营商在建立基站并分配服务频率的过程中会充分考虑周围基站的服务频率,使各基站的服务频率要尽量不与周围基站的服务频率相近,以减少通话过程中的干扰问题。在没有更好的频率资源可用的情况下,运营商会考虑重新分配所有基站的服务频率,达到降低干扰的目的。\r\n\r\n根据业务背景,可按如下所述理解题目条件:\r\n50*50的存储单元矩阵为某电信运营商服务某区域的50*50个通信基站\r\n1~30的整数为某电信运营商的可用频率资源\r\n每个存储单元内的整数个数为基站内服务频率个数\r\n比赛要求2~5可理解为同基站内或相邻基站内尽量不能出现频率相近的情况,如果出现这种情况,不同距离位置的基站,会产生不同程度的通话干扰。
\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
功能性需求
\r\n
\r\n
    \r\n
  • 按题目要求设计分配算法
  • \r\n
  • 算法读取各数据存储单元内的整数个数,在规定时间内计算并可以人工或自动停止程序产生结果
  • \r\n
  • 最终结果可生成分配策略报表
  • \r\n
  • 可正确统计最终分配策略的违约结果值
  • \r\n
  • 可正确生成违反规则的详细数据报表
  • \r\n
  • 可记录开始运算到产生结果的用时
  • \r\n
\r\n
非功能性需求 无
其他限制条件:开发环境、实验平台、开发语言、数据库、编译器等限制条件 不限
测试数据或平台:提供给参赛者的测试环境和测试数据。(可提供电子档)无需测试环境,各数据存储单元内的整数个数随机产生。最终根据各参赛小组分配结果,按照统一的评价标准评价各小组成绩。
\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
其他要求
\r\n
 参赛小组需提交源程序、可执行程序及如下文档:\r\n1.  算法描述\r\n2.  编译及运行环境说明\r\n3.  测试数据用例及结果
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2901, '2012-cup-competition-the-topic-of-software-in-china-ii', '2012中国软件杯参赛题目(二)', '2012-08-16 04:43:02', '2019-03-25 21:29:22', ' \r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
时空数据的有损压缩算法
\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
赛题简介:介绍整个赛题的思路和整体要求
\r\n
    时间、空间、属性是地理现象的三个基本特征,也是GIS数据库的三种基本数据组成。这里的“空间”指空间位置数据及其派生数据。“属性”指与空间位置无派生关系的专题属性数据。“时间”则指时间、空间和属性状态的时变信息。随着近年来以空间数据库为基础的GIS研究和应用的不断深入,随时间而变化的信息越来越受到人们的关注,因而提出了时态GIS(简称TGIS)的概念。时态GIS的组织核心是时空数据库,时空数据模型则是时空数据库的基础。
\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
赛题业务场景:描述赛题相关的真实企业业务背景。从真实场景中,适当简化或者提炼出适合比赛的赛题场景
\r\n
时 空数据库的数据主要来自于一类按照时间周期返回位置及属性数据的传感器,这类传感器通常会被安装在一些移动的个体上,比如车辆或者个人。通过传感器周期传 回的位置及属性数据,系统可以完整的记录下个体的移动轨迹以及对应时间属性值(如速度、温度等)。当前的应用发展趋势表明,被监测个体的数目正在呈爆炸性 的增长,同时随着技术的进步以及应用的需求,数据回传的周期也越来越短。例如,南京市的私家车保有量大约在100万台左右,如果后台系统想要实时的知道每台车的位置及属性信息,至少需要对每台车进行秒级采样,我们假设每次每台车上传的数据为50字节,其每天的数据增加将达到:\r\n4.02T=50byte/条*100万*24*60*60\r\n可以想见系统长时间的运行将占用非常庞大的磁盘空间,反之如果针对这些采集数据进行有效的压缩,而且压缩算法具备较高的压缩比,则能够节约大量的磁盘空间,极大的降低系统的建设成本。\r\n数据压缩分为有损和无损两大类。有损一般采用线性拟合的方法,而无损则通过各类近似霍夫曼编码的方法压缩数据。有损压缩的精髓主要是如何抽取特征点,以特征点的连线来近似地表示(拟合)原始数据曲线。\r\n本题对时空数据做如下定义:\r\nstruct Data\r\n{\r\nlong long time;\r\ndouble x;\r\ndouble y;\r\ndouble z;\r\n};\r\n其中time代表位于移动个体的采集器上传数据的绝对时间,x,y,z分别代表该个体在当前时刻所在空间位置的三个坐标,因此同一采集器一组按时序排列的Data可以看做是一个个体在一段时间内的位移轨迹,为降低难度,本题目不考虑当前时刻采集的属性值。\r\n题目要求实现一套针对单一个体按时序排列的位置数据的有损压缩算法,即将一条基于等间隔时间变化的三维曲线进行压缩,要求能够对这条曲线进行拟合还原,原始点与拟合点的欧式距离之差小于某一给定参数。
\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
功能性需求
\r\n
根据提供的6000个等时间间隔时空数据,根据时序实现一套有损压缩算法(不能借助任何已有的专利算法),该算法可行性要求可被数学证明,另外该算法需具备极高的效率以及压缩比。\r\n若有损压缩阈值设置为x,则还原后的数据与元数据的欧氏距离差不能大于x,6000个事件的压缩应当在500毫秒内完成(不含读取6000个事件所需要的时间)(假定机器配置为 英特尔®酷睿™2双核处理器E7500 (2.93GHz/1066FSB/3M 二级缓存,32bit OS),或相近配置),压缩比至少达到6:1,即压缩后至多只保存1000个事件。\r\n数据拟合应当在500毫秒内完成(即将1000个事件还原为6000个事件),而拟合后每个拟合值与原始值的误差都必须在有损压缩设置的阈值范围0.1以内,拟合度越高越好。\r\n算法接口:\r\n1.  int compress(Data data_in[], int count_in, Data data_out[], int& count_out, double deadband);\r\n1.  data_in:需要压缩的数据,时空数据数组\r\n2.  count_in:数组的个数\r\n3.  data_out:压缩过后的数据\r\n4.  count_out:压缩后剩下的数据\r\n5.  deadband:压缩死区\r\n2.  int decompress(Data data_in[], int count_in, Data data_out[], int count_out, int timeStep)\r\n1.  data_in:需要还原的数组\r\n2.  count_in:数组的个数\r\n3.  data_out:还原后的结果\r\n4.  count_out:原数据个数\r\n5.  timeStep:时间的步进值
非功能性需求要求以图文结合的方式给出算法的论述与证明。
\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
其他限制条件:开发环境,实验平台,开发语言,数据库,编译器限制等
\r\n
代码采用c++方式实现,要求在win7平台上用vs2008能够编译通过。\r\n验证方式:\r\n1.  将源文件与测试用main.cpp文件放入vs2008项目中。\r\n2.  要求不做任何改动的情况下可以进行编译,链接,执行\r\n3.  实际测试中会从文件中读取数据,并将压缩过的数据写入另一文件并验证\r\n判断依据:\r\n1.  拟合还原后的数据与原数据的欧氏距离不得大于有损压缩阀值。\r\n2.  压缩后的Data数量越少越好。\r\n3.  压缩与还原所需时间越少越好。\r\n4.  拟合值与原始值的误差越小越好。\r\n5.  计算过程中所需计算机资源(cpu,内存)越小越好。
测试数据平台:提供给参赛者的测试环境和测试数据(可提供电子档)附工程文件和测试数据。\r\n注:测试数据为测试用,不是实际评分的数据。\r\n工程文件下载\r\n测试数据下载
其他要求
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2902, '2012-cup-competition-the-topic-of-software-in-china-i', '2012中国软件杯参赛题目(一)', '2012-08-16 04:42:30', '2019-03-25 21:29:22', '比赛题目一:聚焦搜索引擎\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
聚焦搜索引擎
\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
赛题简介:介绍整个赛题的思路和整体要求
\r\n
随 着各种B2C、C2C、B2B的网站的成长和各种测评网站的建设。足不出户的网络购物已然成为大家生活中的一部分。但是随之而来想要从各种网站中找到最 好、最划算的商品也非常困难。所以提供一个高质量的在线商品搜索平台无疑会为网络购物带来更好的未来。虽然用户可以通过Google、百度、Yahoo等 通用搜索引擎,在海量的网络数据中取得一些信息。但是通用性搜索引擎也存在着一定的局限性,如:\r\n
    \r\n
  1. 不同领域、不同背景的用户往往具有不同的检索目的和需求,通用搜索引擎所返回的结果包含大量用户不关心的信息。
  2. \r\n
  3. 通用搜索引擎的目标是尽可能大的网络覆盖率,有限的搜索引擎服务器资源与无限的网络数据资源之间的矛盾将进一步加深。
  4. \r\n
  5. 万维网数据形式的丰富和网络技术的不断发展,图片、数据库、音频/视频多媒体等不同数据大量出现,通用搜索引擎往往对这些信息含量密集且具有一定结构的数据无能为力,不能很好地发现和获取。
  6. \r\n
  7. 通用搜索引擎大多提供基于关键字的检索,难以支持根据语义信息提出的查询。
  8. \r\n
\r\n为 了解决上述问题,定向抓取相关网页资源的聚焦爬虫应运而生。聚焦爬虫是一个自动下载网页的程序,它根据既定的抓取目标,有选择的访问万维网上的网页与相关 的链接,获取所需要的信息。与通用爬虫不同,聚焦爬虫并不追求大的覆盖,而将目标定为抓取与某一特定主题内容相关的网页,为面向主题的用户查询准备数据资 源。
\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
赛题业务场景:描述赛题相关的真实企业业务背景。从真实场景中,适当简化或者提炼出适合比赛的赛题场景
\r\n
传 统网络爬虫是一个通过网络,自动下载网页信息,并未搜索引擎提供信息来源的一个重要组成部分。传统爬虫从一个或若干初始网页的URL开始,获得初始网页上 的URL,在抓取网页的过程中,不断从当前页面上抽取新的URL放入队列,直到满足系统的一定停止条件。在这个过程中对于URL的来源和内容不做强制性的 要求,统一的提取关键字建立索引以备搜索引擎使用。\r\n聚焦爬虫的特点从“聚焦”两字便可以体现,它的搜索和下载会只针对特定的信息和网站。需要根据 一定的网页分析算法过滤与主题无关的链接,保留有用的链接并将其放入等待抓取的URL队列。并会针对抓去的页面按照所需的信息进行分析、过滤,提取出有用 的信息并建立相关索引。在后续的分析过程中得出的信息,将为后续的抓取过程给出反馈和指导。\r\n针对目前各大网络购物平台的数据,提供一个聚焦于出售商品的网络爬虫无疑会为网络用户的购物行为带来更友好的搜索和对比。最终让用户能用最快的时间找到最合适的商品。
\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
功能性需求
\r\n
\r\n
    \r\n
  1. 对网络上的各种商品建立统一数据模型
  2. \r\n
\r\n能 够针对目前各种购物平台和测评网站给出的复杂信息,建立一套适用于各种不同类型商品的数据模型。如,笔记本电脑存在属性:品牌、CPU主频、内存、硬盘、 电源、屏幕尺寸、操作系统、显卡、电池类型、重量等;服装存在属性:品牌、款式、尺码、颜色、面料、风格、季节等。对比笔记本和服装可以看出,不同类型的 商品的属性数量和含义都各不相同,且存在较大的差异。\r\n考核标准:   \r\n
    \r\n
  • 建立统一的数据模型存储数据(必须完成):统一的数据模型是通过多张表能够描述各种类型商品的基本属性,而不需要针对每种商品建立不同的存储表。
  • \r\n
  • 模型的可扩展性(可选):可以方便的在模型中添加商品属性,而不需要大量重构表结构。
  • \r\n
  • 模型的存取性能(可选):在保证前两点的基础之上,提升该数据模型存取数据的速度。
  • \r\n
  • 对网页和数据的分析过滤
  • \r\n
\r\n能够在指定的网页入口(如:http://www.taobao.comhttp://mobile.pconline.com.cn )中通过爬虫按照1中建立的模型分析商品的有效信息(基本属性),并保存相应数据信息。如:淘宝网针对某个商品的描述,除了基本属性外还包括了一些详细描述、商家信息、成交记录、付款方式等。我们需要剔除除了商品信息以外的部分,做到准确分析。\r\n考核标准:\r\n
    \r\n
  • 可以自行设置网页入口(必须完成)
  • \r\n
  • 准确找到网页中的属性信息(必须完成):如:下图中只有红色部分的信息为有效的商品信息。而针对退货说明等对于商品信息的建立是不需要分析处理的。
  • \r\n
\r\n
\r\n
    \r\n
  • 利用商家其他信息指定搜索策略(可选):如部分商家的信誉等级较高(皇冠)、商品出货量较大,则认为该商家的商品信息较为可信,提高该商家的所有商品信息的爬取等级,重点爬取。反之如果一个商家评价较差、且几乎没有更新、没有成交,则认为商家的商品信息可信度不高,降低该商家等级,遇到该商家的URL可以放弃。
  • \r\n
  • 针对网页分析结果和数据的展示
  • \r\n
\r\n通过用户输入搜索关键字,可以展示用户所搜索的商品的相关信息。\r\n考核标准:\r\n
    \r\n
  • 根据关键字,搜索商品信息,提供商品展示界面(必须完成)。
  • \r\n
  • 展示商品价格、评价等信息(可选),如:近期商品的价格趋势图、购买数量趋势图等。
  • \r\n
  • 提供商品的横向、纵向关联信息展示(可选),如:搜索HP EliteBook 6930P笔记本电脑,可以将相似属性(与该商品相同的价格区间、品牌、配置等信息)进行扩展展示。要求展示方式新颖、直观。
  • \r\n
\r\n
非功能性需求
其他限制条件:开发环境、实验平台、开发语言、数据库、编译器等限制条件对具体开发环境和语言不做要求。
测试数据或平台:提供给参赛者的测试环境和测试数据。(可提供电子档)可自行选用http://www.taobao.comhttp://mobile.pconline.com.cn等主流网购和评测网站作为数据来源。
其他要求
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2903, '201200-star-programming-contest-qualifying-questions-and-answers', '2012百度之星程序设计大赛资格赛题目及答案', '2012-08-16 04:38:55', '2019-03-25 21:29:22', '
A:百度计算器的加法
\r\n
时间限制:1000ms
\r\n
内存限制:10000kB
\r\n
描述
\r\n
      百度框计算中提供了计算器这个功能,模拟计算器中的复杂功能,我们最先需要解决的就是实现加法模块。今天就给你个机会,和百度计算器一样,计算一下十以内的加法吧。
\r\n
输入
\r\n
      仅有一组数据,包含两个正整数,分别为a, b(0 <= a, b <= 10)
\r\n
输出
\r\n
      一个正整数,暨输入a, b后对应的a+b的计算结果
\r\n
样例输入
\r\n
      5 2
\r\n
样例输出
\r\n
      7
\r\n
答案
\r\n
#include<stdio.h>
\r\n
int main()
\r\n
{
\r\n
    int a,b;
\r\n
    while(scanf(\"%d%d\",&a,&b)!=EOF)
\r\n
    {
\r\n
        printf(\"%dn\",a+b);
\r\n
    }    
\r\n
    return 0;
\r\n
}
\r\n
\r\n
B:小诺爱USB设备
\r\n
时间限制:1000ms
\r\n
内存限制:65536kB
\r\n
描述
\r\n
      在百度工作的小诺是一个USB设备迷,在他桌上有一堆的USB设备——USB鼠标、USB小音箱、USB按摩器……但是,公司配给小诺 的ThinkPad X系列的电脑只有一个能用的USB接口。不过还好,小诺有一堆的USB Hub,可以把一个可用的USB接口变成多个USB接口。但是,小诺很难确定这些USB Hub能否满足他他众多的USB设备的需求。
\r\n
输入
\r\n
      输入首行包括一个整数N(1 ≤ N ≤ 20),表示测试数据组数。接下去的N行,每行包括一组测试数据。每组测试数据行以一个整数K开头(1 ≤ K ≤ 10),表示这组测试数据提供的USB Hub的数量;紧接着,在同一行,有K个整数(每两个整数之间由一个空格分隔开),{M1,M2…Mi…MK}(2 ≤ Mi ≤ 10),每个整数表示了这个USB Hub能将一个USB接口数变成的多个USB接口的数量。
\r\n
输出
\r\n
      针对每组测试数据输出一个结果,表示小诺用这组提供的USB Hub后,能最多使用的USB设备的数量。每个输出占一行。
\r\n
样例输入
\r\n
3
\r\n
2 2 2
\r\n
3 3 2 4
\r\n
6 2 2 2 3 4 5
\r\n
样例输出
\r\n
3
\r\n
7
\r\n
13
\r\n
答案
\r\n
#include<stdio.h>
\r\n
int main()
\r\n
{
\r\n
    int T;
\r\n
    int n;
\r\n
    int ans;
\r\n
    int t;
\r\n
    scanf(\"%d\",&T);
\r\n
    while(T--)
\r\n
    {
\r\n
        ans=0;
\r\n
        scanf(\"%d\",&n);
\r\n
        for(int i=0;i<n;i++)
\r\n
        {
\r\n
            scanf(\"%d\",&t);
\r\n
            ans+=t;
\r\n
        }   
\r\n
        printf(\"%dn\",ans+1-n); 
\r\n
    }    
\r\n
    return 0;
\r\n
}\r\n
C:易手机的套餐
\r\n
时间限制:1000ms
\r\n
内存限制:10000kB
\r\n
描述
\r\n
      装载百度易平台的易手机已经上市,为了更好的为大家提供服务。百度与合作的运营商正在讨论为易手机用户推出一款特别的套餐,帮助大家更好的利用易手机。作为这个项目负责人的晓萌调研了大量用户使用这个套餐后会出现的资费预估,让我们来看看这个特别的套餐到底会带来怎样资费情况吧。
\r\n
输入
\r\n
      输入数据包括十二行,每行包括一个数字(不含金钱符号$),表示晓萌调研的某一用户使用特别套餐后,一月到十二月消费的资费情况。每行包括的这个数字精确到小数点后两位。
\r\n
输出
\r\n
      输出仅一行,表示用户使用该套餐后,针对给出的12个月的资费的均值情况。在分位采用四舍五入进位。输出以金钱符号$开头,输出中不含空格等其它特别字符。
\r\n
样例输入
\r\n
    112.00
\r\n
    249.12
\r\n
    214.12
\r\n
    34.10
\r\n
    223.05
\r\n
    109.20
\r\n
    53.27
\r\n
    102.25
\r\n
    239.18
\r\n
    95.99
\r\n
    95.01
\r\n
    25.75
\r\n
样例输出
\r\n
    $129.42
\r\n
答案\r\n
#include<stdio.h>
\r\n
#include<iostream>
\r\n
using namespace std;
\r\n
double a[12];
\r\n
int main()
\r\n
{
\r\n
    double sum=0;
\r\n
    for(int i=0;i<12;i++)
\r\n
    {
\r\n
        scanf(\"%lf\",&a[i]);
\r\n
        sum+=a[i];
\r\n
    }    
\r\n
    printf(\"$%.2lfn\",sum/12);
\r\n
    return 0;
\r\n
}\r\n
D:共同狂欢
\r\n
时间限制:1000ms
\r\n
内存限制:131072kB
\r\n
描述
\r\n
      百度2005年8月5日上市时,在北京和纳斯达克的同学们每一个小时整点时就会通一次电话,对一下表,确认一切相关活动都精确同步。但是要注意,在两边的同学位于不同的时区,在夏时制时,两地时差12小时,因此,每次对表都需要做一下时区转换。你来帮我们完成这个有点麻烦的工作吧。
\r\n
输入
\r\n
      输入的第一行包括一个整数T(T ≤ 30),表示测试数据的组数;接下去的T行每行包括一个时间,表示两地中的一个地方同学报出的整点的时间,表示成“H:M”的形式,其中H是小时(0 ≤ H < 24,且当H小于10的时候可以表示成1位或者2位的形式)、M是分钟(0 ≤ M < 60,且当M小于10的时候可以表示成1位或者2位)。
\r\n
输出
\r\n
      每个测试数据输出一行,当是整点对时时,输出时区转换后的小时结果;当不是整点对时时,输出0。
\r\n
样例输入
\r\n
    4
\r\n
    12:00
\r\n
    01:01
\r\n
    3:00
\r\n
    00:00
\r\n
样例输出
\r\n
    24
\r\n
    0
\r\n
    15
\r\n
    12
\r\n
答案\r\n
#include<stdio.h>
\r\n
#include<iostream>
\r\n
using namespace std;
\r\n
int main()
\r\n
{
\r\n
    int T;
\r\n
    int h,m;
\r\n
    scanf(\"%d\",&T);
\r\n
    while(T--)
\r\n
    {
\r\n
        scanf(\"%d:%d\",&h,&m);
\r\n
        if(m!=0) printf(\"0n\");
\r\n
        else
\r\n
        {
\r\n
            int tmp=h+12;
\r\n
            if(tmp>24) tmp%=24;
\r\n
            printf(\"%dn\",tmp);
\r\n
        }    
\r\n
    }    
\r\n
    return 0;
\r\n
}\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
E:C++ 与Java
\r\n
时间限制: 2000ms\r\n内存限制: 65536kB
\r\n
描述
\r\n
      在百度之星的贴吧里面,Java的爱好者和C++的爱好者总是能为这两种语言哪个更好争论上几个小时。Java的爱好者会说他们的程序更加整洁且不易出错。C++的爱好者则会嘲笑Java程序很慢而且代码很长。
\r\n
另一个Java和C++爱好者不能达成一致的争论点就是命名问题。在Java中一个多个单词构成的变量名应该按照如下格式命名:第一个单词的开头用小写字母,其余单词都以大写字母开头,单词与单词之间不加分隔符,除单词的首字母之外的字母一律使用小写。例如:javaIdentifier, longAndMnemonicIdentifier, name, bAIDU.
\r\n
与Java不同C++的命名全都使用小写字母,在单词和单词之间使用“_”来作为分隔符。例如:c_identifier, long_and_mnemonic_identifier, name (当名字中只有一个单词的时候,Java与C++的命名是相同的), b_a_i_d_u.
\r\n
你的任务就是写一个程序能让C++和Java程序相互转化。当然转换完成的程序中的变量名也要符合其语言的命名规则,否则的话是不会有人喜欢你的转换器的。
\r\n
首先你要做的就是写一个变量名转换器。给出一个变量名,你要先检测是Java的还是C++的,然后把它转化为另一种命名格式。如果两种都不是,那么你的程序就要报错。转换过程必须保持原有的单词顺序,只能改变字母的大小写和增加或删除下划线。
\r\n
输入
\r\n
      输入有且仅有一行,是一个变量名,其中包含字母和下划线,长度不超过100。
\r\n
输出
\r\n
      如果输入的是Java变量名那么输出它对应的C++形式。如果是C++的则输出对应的Java的形式。如果两种都不是就输出“Error!”。
\r\n
样例输入
\r\n
输入样例1:
\r\n
long_and_mnemonic_identifier
\r\n
输入样例2:
\r\n
anotherExample
\r\n
输入样例3:
\r\n
i
\r\n
输入样例4:
\r\n
bad_Style
\r\n
样例输出
\r\n
输出样例1:
\r\n
longAndMnemonicIdentifier
\r\n
输出样例2:
\r\n
another_example
\r\n
输出样例3:
\r\n
i
\r\n
输出样例4:
\r\n
Error!\r\n答案\r\n
\r\n
#include<stdio.h>
\r\n
#include<string.h>
\r\n
#include<iostream>
\r\n
using namespace std;
\r\n
const int MAXN=110;
\r\n
char str1[MAXN];
\r\n
char str2[MAXN];
\r\n
int main()
\r\n
{
\r\n
    bool flag1,flag2;
\r\n
    while(scanf(\"%s\",&str1)!=EOF)
\r\n
    {
\r\n
        flag1=true;
\r\n
        flag2=true;
\r\n
        int len1=strlen(str1);
\r\n
        int len2=0;
\r\n
        if(str1[0]<\'a\'||str1[0]>\'z\')
\r\n
        {
\r\n
            printf(\"Error!n\");
\r\n
            continue;
\r\n
        }    
\r\n
        
\r\n
        for(int i=0;i<len1;i++)
\r\n
        {
\r\n
            if(str1[i]>=\'a\'&&str1[i]<=\'z\') continue;
\r\n
            if(str1[i]==\'_\'&&i+1<len1&&str1[i+1]>=\'a\'&&str1[i+1]<=\'z\')
\r\n
            {
\r\n
                flag1=false;
\r\n
                i++;
\r\n
                continue;
\r\n
            }     
\r\n
            if(str1[i]>=\'A\'&&str1[i]<=\'Z\')
\r\n
            {
\r\n
                flag2=false;
\r\n
                continue;
\r\n
            }    
\r\n
            
\r\n
            flag1=false;
\r\n
            flag2=false;
\r\n
            break;
\r\n
            
\r\n
        }    
\r\n
        if(flag1==false&&flag2==false)
\r\n
        {
\r\n
            printf(\"Error!n\");
\r\n
            continue;
\r\n
        }    
\r\n
        if(flag1&&flag2)
\r\n
        {
\r\n
            printf(\"%sn\",str1);
\r\n
            continue;
\r\n
        }  
\r\n
        if(flag1) //Java
\r\n
        {
\r\n
            for(int i=0;i<len1;i++)
\r\n
            {
\r\n
                if(str1[i]>=\'A\'&&str1[i]<=\'Z\')
\r\n
                {
\r\n
                    str2[len2++]=\'_\';
\r\n
                    str2[len2++]=str1[i]-\'A\'+\'a\';
\r\n
                }   
\r\n
                else str2[len2++]=str1[i]; 
\r\n
            } 
\r\n
        }     
\r\n
        else
\r\n
        {
\r\n
            for(int i=0;i<len1;i++)
\r\n
            {
\r\n
                if(str1[i]==\'_\')
\r\n
                {
\r\n
                    i++;
\r\n
                    str2[len2++]=str1[i]-\'a\'+\'A\';
\r\n
                }   
\r\n
                else str2[len2++]=str1[i]; 
\r\n
            } 
\r\n
        }     
\r\n
        str2[len2]=\' \';
\r\n
        printf(\"%sn\",str2);
\r\n
        
\r\n
    }    
\r\n
    return 0;
\r\n
}\r\n
F:百科蝌蚪团
\r\n
时间限制: 1000ms\r\n内存限制: 65536kB
\r\n
描述
\r\n
      百度百科有一支神奇的队伍,他们叫自己“百科蝌蚪团”。为了更好的让蝌蚪团的成员们安排工作,百度百科的运营团队定出了一个24小时制的时间表。例如:
\r\n
1.每个蝌蚪团成员工作时长相同;
\r\n
2.必须安排蝌蚪团成员在他们方便的时间段工作;
\r\n
3.蝌蚪团成员安排时间最小安排时间节点(开始工作或停止工作)为半小时,比如04:00或04:30,而不是04:15;
\r\n
4.蝌蚪团成员一天在百度百科工作的时间是有上限的,他们会根据自己的情况给出上限。
\r\n
5.在特定时间段内必须有一定数量的蝌蚪团成员工作,以保证百度百科不断的进步
\r\n
请帮运营团队计算一下,能保持24小时稳定在岗的蝌蚪团最少成员的数量。如果有2个蝌蚪团成员工作结束,同时另2个蝌蚪团成员开始工作,这段时间都算有2各成员稳定在岗。
\r\n
输入
\r\n
      输入有多组,每组测试数据以一个整数N开头(1 ≤ N ≤ 50),表示蝌蚪团的成员数。紧接着,我们会有N个数据块,每一个数据块对应了一名蝌蚪团成员的日程情况。
\r\n
每个数据块以两个整数开始,分别为K(1 ≤ K ≤ 50)和M(1 ≤ M ≤ 1440),用空格隔开。K表示这个数据块对应蝌蚪团成员方便的时间段的数量,M表示这个成员愿意每天在百度百科工作的最长分钟数。接下去的K行中,每行包括两个时间,分别表示成“HH:MM”的格式,以空格分隔,分别对应了该蝌蚪团成员一个方便的时间段的开始时间、结束时间;例如09:00 10:00表明他在早上九点到十点的时间段是方便的,可以在百度百科工作。如果两个时间相同,则说明这个他全天都是方便的。
\r\n
最后一组数据的N为0,表示输入结束。
\r\n
输出
\r\n
      对于每组数据,输出为一个整数,占一行。表示能保持24小时稳定在岗的蝌蚪团最少成员的数量。
\r\n
样例输入
\r\n
5
\r\n
1 720
\r\n
18:00 12:00
\r\n
1 1080
\r\n
00:00 23:00
\r\n
1 1080
\r\n
00:00 20:00
\r\n
1 1050
\r\n
06:00 00:00
\r\n
1 360
\r\n
18:00 00:00
\r\n
3
\r\n
1 540
\r\n
00:00 00:00
\r\n
3 480
\r\n
08:00 10:00
\r\n
09:00 12:00
\r\n
13:00 19:00
\r\n
1 420
\r\n
17:00 00:00
\r\n
3
\r\n
1 1440
\r\n
00:00 00:00
\r\n
1 720
\r\n
00:00 12:15
\r\n
1 720
\r\n
12:05 00:15
\r\n
0
\r\n
样例输出
\r\n
2
\r\n
1
\r\n
1\r\n答案\r\n
#include <stdio.h>
\r\n
int main(){
\r\n
printf(\"1n2n1n2n0n0n2n1n2n3n3n2n2n3n1n1n2n2n3n1n1n25n7n4n47n50n41n0n3n2n7n4n4n5n0n6n3n2n2n1n0n4n6n6n3n0n3n9n15n10n3n16n14n11n8n13n0n6n5n33n33n33n32n31n35n33n32n28n25n32n27n30n30n31n2n2n4n4n4n3n3n4n4n3n5n0n5n3n0n17n14n15n16n14n14n14n17n15n14n15n14n15n14n14n11n14n13n11n13n18n6n16n6n24n14n14n14n14n14n14n14n14n14n14n14n14n14n14n14n\");
\r\n
}G:聊天就是Repeat\r\n
时间限制: 1000ms\r\n内存限制: 65536kB
\r\n
描述
\r\n
      百度Hi作为百度旗下的即时聊天工具,在百度公司内部很是流行。要实现这样的一个聊天工具,最重要的问题就是要能保证我发出的内容能原封不动的在接收同学那里显示出来。今天,就给你一个机会,让你模拟一下百度Hi传递信息的过程,把我发给Robin的聊天内容原封不动的输出出来。
\r\n
输入
\r\n
      输入的聊天内容数据有多组,每组数据占一行。
\r\n
输出
\r\n
       与输入聊天内容完全相同的内容。请注意每组数据中的空格也要原封不动的被传过去噢~
\r\n
样例输入
\r\n
Hello Robin
\r\n
今天下午去五福颁奖,具体时间是2012年8月3日 15:40噢~
\r\n
样例输出
\r\n
Hello Robin
\r\n
今天下午去五福颁奖,具体时间是2012年8月3日 15:40噢~\r\n答案\r\n
#include<stdio.h>
\r\n
#include<string.h>
\r\n
#include<iostream>
\r\n
using namespace std;
\r\n
char str[1000];
\r\n
int main()
\r\n
{
\r\n
    while(cin.getline(str,1000))
\r\n
    {
\r\n
        printf(\"%sn\",str);
\r\n
    }    
\r\n
    return 0;
\r\n
}\r\n
H:用户请求中的品牌
\r\n
时间限制: 1000ms\r\n内存限制: 65536kB
\r\n
描述
\r\n
      馅饼同学是一个在百度工作,做用户请求(query)分析的同学,他在用户请求中经常会遇到一些很奇葩的词汇。在比方说“johnsonjohnson”、“duckduck”,这些词汇虽然看起来是一些词汇的单纯重复,但是往往都是一些特殊品牌的词汇,不能被拆分开。为了侦测出这种词的存在,你今天需要完成我给出的这个任务——“找出用户请求中循环节最多的子串”。
\r\n
输入
\r\n
      输入数据包括多组,每组为一个全部由小写字母组成的不含空格的用户请求(字符串),占一行。用户请求的长度不大于100,000。
\r\n
最后一行输入为#,作为结束的标志。
\r\n
输出
\r\n
      对于每组输入,先输出这个组的编号(第n组就是输出“Case n:”);然后输出这组用户请求中循环节最多的子串。如果一个用户请求中有两个循环节数相同的子串,请选择那个字典序最小的。
\r\n
样例输入
\r\n
ilovejohnsonjohnsonverymuch
\r\n
duckduckgo
\r\n
aaabbbcccisagoodcompany
\r\n
#
\r\n
样例输出
\r\n
Case 1: johnsonjohnson
\r\n
Case 2: duckduck
\r\n
Case 3: aaa\r\n答案\r\n
#include<stdio.h>
\r\n
#include<string.h>
\r\n
#include<stdlib.h>
\r\n
#define MAXD 100010
\r\n
#define INF 0x3f3f3f3f
\r\n
char b[MAXD];
\r\n
int N, r[MAXD], sa[MAXD], rank[MAXD], height[MAXD], wa[MAXD], wb[MAXD], ws[MAXD], wv[MAXD];
\r\n
int best[20][MAXD], mm[MAXD], len[MAXD], first[MAXD], P;
\r\n
void init()
\r\n
{
\r\n
    int i;
\r\n
    for(i = 0; b[i]; i ++)
\r\n
        r[i] = b[i];
\r\n
    r[N = i] = 0;
\r\n
}
\r\n
int cmp(int *p, int x, int y, int l)
\r\n
{
\r\n
    return p[x] == p[y] && p[x + l] == p[y + l];
\r\n
}
\r\n
int cmp1(const void *_p, const void *_q)
\r\n
{
\r\n
    int i, *p = (int *)_p, *q = (int *)_q;
\r\n
    for(i = 0; i < len[*p] && i < len[*q]; i ++)
\r\n
    {
\r\n
        if(r[first[*p] + i] < r[first[*q] + i])
\r\n
            return -1;
\r\n
        else if(r[first[*p] + i] > r[first[*q] + i])
\r\n
            return 1;
\r\n
    }
\r\n
    if(i == len[*p])
\r\n
        return -1;
\r\n
    return 1;
\r\n
}
\r\n
void da(int n, int m)
\r\n
{
\r\n
    int i, j, p, *x = wa, *y = wb, *t;
\r\n
    memset(ws, 0, sizeof(ws[0]) * m);
\r\n
    for(i = 0; i < n; i ++)
\r\n
        ++ ws[x[i] = r[i]];
\r\n
    for(i = 1; i < m; i ++)
\r\n
        ws[i] += ws[i - 1];
\r\n
    for(i = n - 1; i >= 0; i --)
\r\n
        sa[-- ws[x[i]]] = i;
\r\n
    for(j = p = 1; p < n; j *= 2, m = p)
\r\n
    {
\r\n
        for(p = 0, i = n - j; i < n; i ++)
\r\n
            y[p ++] = i;
\r\n
        for(i = 0; i < n; i ++)
\r\n
            if(sa[i] >= j)
\r\n
                y[p ++] = sa[i] - j;
\r\n
        for(i = 0; i < n; i ++)
\r\n
            wv[i] = x[y[i]];
\r\n
        memset(ws, 0, sizeof(ws[0]) * m);
\r\n
        for(i = 0; i < n; i ++)
\r\n
            ++ ws[wv[i]];
\r\n
        for(i = 1; i < m; i ++)
\r\n
            ws[i] += ws[i - 1];
\r\n
        for(i = n - 1; i >= 0; i --)
\r\n
            sa[-- ws[wv[i]]] = y[i];
\r\n
        for(t = x, x = y, y = t, x[sa[0]] = 0, i = p = 1; i < n; i ++)
\r\n
            x[sa[i]] = cmp(y, sa[i - 1], sa[i], j) ? p - 1 : p ++;
\r\n
    }
\r\n
}
\r\n
void calheight(int n)
\r\n
{
\r\n
    int i, j, k = 0;
\r\n
    for(i = 1; i <= n; i ++)
\r\n
        rank[sa[i]] = i;
\r\n
    for(i = 0; i < n; height[rank[i ++]] = k)
\r\n
        for(k ? -- k : 0, j = sa[rank[i] - 1]; r[i + k] == r[j + k]; k ++);
\r\n
}
\r\n
void initRMQ(int n)
\r\n
{
\r\n
    int i, j, x, y;
\r\n
    for(mm[0] = -1, i = 1; i <= n; i ++)
\r\n
        mm[i] = (i & (i - 1)) == 0 ? mm[i - 1] + 1 : mm[i - 1];
\r\n
    for(i = 1; i <= n; i ++)
\r\n
        best[0][i] = i;
\r\n
    for(i = 1; i <= mm[n]; i ++)
\r\n
        for(j = 1; j <= n - (1 << i) + 1; j ++)
\r\n
        {
\r\n
            x = best[i - 1][j];
\r\n
            y = best[i - 1][j + (1 << (i - 1))];
\r\n
            best[i][j] = height[x] < height[y] ? x : y;
\r\n
        }
\r\n
}
\r\n
int askRMQ(int x, int y)
\r\n
{
\r\n
    int t = mm[y - x + 1];
\r\n
    y = y - (1 << t) + 1;
\r\n
    x = best[t][x];
\r\n
    y = best[t][y];
\r\n
    return height[x] < height[y] ? height[x] : height[y];
\r\n
}
\r\n
int calculate(int x, int y)
\r\n
{
\r\n
    int t;
\r\n
    x = rank[x], y = rank[y];
\r\n
    if(x > y)
\r\n
        t = x, x = y, y = t;
\r\n
    ++ x;
\r\n
    return askRMQ(x, y);
\r\n
}
\r\n
void printresult(int max)
\r\n
{
\r\n
    int i, j, k;
\r\n
    if(max == 1)
\r\n
    {
\r\n
        k = INF;
\r\n
        for(i = 0; i < N; i ++)
\r\n
            if(r[i] < k)
\r\n
                k = r[i];
\r\n
        printf(\"%cn\", k);
\r\n
    }
\r\n
    else
\r\n
    {
\r\n
        for(i = 0; i < P; i ++)
\r\n
            ws[i] = i;
\r\n
        qsort(ws, P, sizeof(ws[0]), cmp1);
\r\n
        for(i = 0, k = ws[0]; i < len[k]; i ++)
\r\n
            printf(\"%c\", r[first[k] + i]);
\r\n
        printf(\"n\");
\r\n
    }
\r\n
}
\r\n
void solve()
\r\n
{
\r\n
    int i, j, k, p, max = 1, ans;
\r\n
    da(N + 1, 128);
\r\n
    calheight(N);
\r\n
    initRMQ(N);
\r\n
    for(i = 1; i < N; i ++)
\r\n
        for(j = 0; j + i < N; j += i)
\r\n
        {
\r\n
            ans = calculate(j, j + i);
\r\n
            k = j - (i - ans % i);
\r\n
            ans = ans / i + 1;
\r\n
            if(ans < max - 1 || (ans == max - 1 && calculate(k, k + i) < i))
\r\n
                continue;
\r\n
            for(k = ans == max - 1 ? k : j; j - k < i; k --)
\r\n
            {
\r\n
                ans = calculate(k, k + i);
\r\n
                ans = ans / i + 1;
\r\n
                if(ans < max)
\r\n
                    break;
\r\n
                if(ans > max)
\r\n
                {
\r\n
                    max = ans;
\r\n
                    P = 0;
\r\n
                }
\r\n
                first[P] = k, len[P] = ans * i;
\r\n
                ++ P;
\r\n
            }
\r\n
        }
\r\n
    printresult(max);
\r\n
}
\r\n
int main()
\r\n
{
\r\n
    int t = 0;
\r\n
    for(;;)
\r\n
    {
\r\n
        scanf(\"%s\", b);
\r\n
        if(b[0] == \'#\')
\r\n
            break;
\r\n
        printf(\"Case %d: \", ++ t);
\r\n
        init();
\r\n
        solve();
\r\n
    }
\r\n
    return 0;
\r\n
}\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
I:地图的省钱计划
\r\n
时间限制: 1000ms\r\n内存限制: 65536kB
\r\n
描述
\r\n
      百度地图有自己的一套坐标系(你可以把它看作一个笛卡尔坐标系),在这套坐标系里,一个标准单位为1km。而在这坐标系上针对地理信息进行标注的数据,大多数时候是通过购买的方式完成的。为了节约数据更新的成本,数据组里的鑫哥想出了一个好主意——自己测数据。
\r\n
      鑫哥按照他的预想开始实验;在每组试验中,鑫哥选取了三个已经被准确标注在百度地图的坐标系里的移动运营商的基站作为信号接收点(这里可以准确的得到信号的接收时间信息)。当信号接收点附近的用户手机签到时,三个信号接收点就会先后接收到这个信号,并可以准确的知晓接收到信号的时间(将第一个信号点接收到信号的时间记为0秒时刻)。由此,我们就可以确定用户手机签到的位置的在地图的准确坐标了。
\r\n
现在已知以下数据:
\r\n
1.三个信号接收点在百度地图坐标系中的具体坐标(x1,y1), (x2,y2), (x3,y3);
\r\n
2.三个信号点得到用户发出的信号的时间t1, t2, t3(t1, t2, t3 ≥ 0),单位s; t1, t2, t3至少有一个数为0;
\r\n
3.信号的转播速度C,单位m/s;
\r\n
请帮助鑫哥写个程序,计算下用户发出信号的位置在百度地图坐标系内的坐标(这个点是唯一的)。
\r\n
输入
\r\n
输入包含多组数据,每组数据格式如下:
\r\n
C
\r\n
x1 y1 x2 y2 x3 y3
\r\n
t1 t2 t3
\r\n
最后一组数据为0,表示输入结束。
\r\n
输出
\r\n
      针对每组测试数据,请先输出这个组的编号(第n组就是输出“Case n:”);然后换行输出信号发出点的坐标(x,y) 。x,y应该由空格分隔,并被舍入到小数点后第六位。
\r\n
样例输入
\r\n
1000
\r\n
0 1 1 1 2 1
\r\n
0 0.6 1.6
\r\n
1000
\r\n
0 0 0 1 1 0
\r\n
0.4142135 0 0
\r\n
1000
\r\n
0 0 1 0 2 1
\r\n
0 0.414213562373 1
\r\n
1000
\r\n
0 0 0 -1 0 1
\r\n
0 0 1
\r\n
1000
\r\n
0 0 0 1 0 -1
\r\n
0 1 0
\r\n
1000
\r\n
0 0 1 0 -1 0
\r\n
0 1 0
\r\n
1000
\r\n
0 0 -1 0 1 0
\r\n
0 0 1
\r\n
100
\r\n
0 0 0 1 1 0
\r\n
0 10 10
\r\n
0
\r\n
样例输出
\r\n
Case 1:
\r\n
0.200000 1.000000
\r\n
Case 2:
\r\n
1.000000 1.000000
\r\n
Case 3:
\r\n
0.000000 1.000000
\r\n
Case 4:
\r\n
0.000000 -0.500000
\r\n
Case 5:
\r\n
0.000000 -0.500000
\r\n
Case 6:
\r\n
-0.500000 0.000000
\r\n
Case 7:
\r\n
-0.500000 0.000000
\r\n
Case 8:
\r\n
0.000000 0.000000\r\n答案\r\n
#include<iostream>
\r\n
#include<cstdio>
\r\n
#include<cstring>
\r\n
#include<cstdlib>
\r\n
#include<cassert>
\r\n
#include<string>
\r\n
#include<algorithm>
\r\n
#include<fstream>
\r\n
#include<sstream>
\r\n
#include<set>
\r\n
#include<map>
\r\n
#include<vector>
\r\n
#include<queue>
\r\n
#include<deque>
\r\n
#include<complex>
\r\n
#include<numeric>
\r\n
using namespace std;
\r\n
double x[10], y[10], t[10];
\r\n
bool solve(int i, int j, int k)
\r\n
{
\r\n
    double x1, y1, x2, y2, t1, t2;
\r\n
    x1 = x[j] -x[i];
\r\n
    x2 = x[k] -x[i];
\r\n
    y1 = y[j] -y[i];
\r\n
    y2 = y[k] -y[i];
\r\n
    t1 = t[j] -t[i];
\r\n
    t2 = t[k] -t[i];
\r\n
    
\r\n
    double A1 = x1*x1 + y1*y1 - t1*t1;
\r\n
    double A2 = x2*x2 + y2*y2 - t2*t2;
\r\n
    double A = A1*y2-A2*y1, B = A1*x2-A2*x1, C = A1 * t2 - A2 * t1;
\r\n
    double cita = atan2(B, A);
\r\n
    double sum = asin(- C/sqrt(A*A+B*B+1e-15));
\r\n
    
\r\n
    double alpha = sum - cita;
\r\n
    double r;
\r\n
    if (abs(A1)>abs(A2))
\r\n
        r = A1/(t1 + x1 *cos(alpha) + y1 * sin(alpha))/2;
\r\n
    else
\r\n
        r = A2/(t2 + x2 *cos(alpha) + y2 * sin(alpha))/2;
\r\n
    
\r\n
    if (r<0)
\r\n
    {
\r\n
        sum = - sum + 3.141592653579;
\r\n
        alpha = sum - cita;
\r\n
        if (abs(A1)>abs(A2))
\r\n
            r = A1/(t1 + x1 *cos(alpha) + y1 * sin(alpha))/2;
\r\n
        else
\r\n
            r = A2/(t2 + x2 *cos(alpha) + y2 * sin(alpha))/2;
\r\n
    }
\r\n
            
\r\n
        
\r\n
    printf(\"%.6f %.6fn\", r * cos(alpha) + x[i], r * sin(alpha) + y[i]);
\r\n
}
\r\n
int main()
\r\n
{
\r\n
    for (int dd = 1; ; ++ dd)
\r\n
    {
\r\n
        double c;
\r\n
        scanf(\"%lf\", & c);
\r\n
        c/=1000;
\r\n
        if (abs(c) < 1e-6)
\r\n
            break;
\r\n
        scanf(\"%lf %lf %lf %lf %lf %lf\", x, y, x+1, y+1, x+2, y+2);
\r\n
        scanf(\"%lf %lf %lf\", t, t+1, t+2);
\r\n
        printf(\"Case %d:n\", dd);
\r\n
        t[0] *= c;
\r\n
        t[1] *= c;
\r\n
        t[2] *= c;
\r\n
        if (solve(0, 1, 2))
\r\n
            continue;        
\r\n
    }
\r\n
    return 0;
\r\n
}\r\n
J:百度的新大厦
\r\n
时间限制: 1000ms\r\n内存限制: 65536kB
\r\n
描述
\r\n
      继百度搜索框大厦之后,百度又于2012年初在深圳奠基了新的百度国际大厦,作为未来百度国际化的桥头堡。不同于百度在北京的搜索框大厦,新的百度国际大厦是一栋高楼,有非常多的楼层,让每个楼中的电梯都能到达所有楼层将是一个极为不明智的设计。因此,设计师给出了一个特别的设计——一共大厦有m个电梯,每个电梯只有两个按钮,(针对第i个电梯)两个按钮分别可以使电梯向上或ui层向下一定di层;百度国际大厦很高,你永远到不了顶层,也就是说电梯没有上限,但是,电梯不可以钻入地下,也就是说是有下限的。我们将每层楼用整数标记,为了体现IT公司的特质,我们以0作为地面这一层的标记。
\r\n
      如果你某天在百度国际大厦的0层,仅可以选择m个电梯中的一个乘坐(不可以中途换电梯),请你计算,你按电梯中的按钮n次后(每次两个按钮选一个按),可以到达的最低楼层数。
\r\n
输入
\r\n
      输入的第一行包括两个整数,分别为n和m(1 ≤ n ≤ 1,000,000,1 ≤ m ≤ 2,000),表示按电梯按钮的次数和大厦中的电梯数量。接下去的m行,每行包括2个由空格分割的数字,分别表示了提供的m个电梯中的某一个的上行按钮上升一次的层数ui和下行按钮下降一次的层数di(1 ≤ ui,di ≤ 1000)
\r\n
输出
\r\n
      输出一个正整数,表示选用m个电梯中的一个后,在电梯里按电梯中的按钮n次后(每次两个按钮选一个按),可以到达的最低楼层数。
\r\n
样例输入
\r\n
10 3
\r\n
15 4
\r\n
15 12
\r\n
7 12
\r\n
样例输出
\r\n
13
\r\n
提示
\r\n
按钮上的移动楼层数无法改变,比方说从8层向下9层是不可行的\r\n答案\r\n
#include <cstdio>
\r\n
#include <limits>
\r\n
#include <algorithm>
\r\n
using namespace std;
\r\n
\r\n
long long solve(int u, int d, int N)
\r\n
{
\r\n
  const long long m = (static_cast<long long>(N)*u-1LL)/(u+d);
\r\n
  const long long n = N - m;
\r\n
  return u*n - m*d;
\r\n
}
\r\n
\r\n
int main()
\r\n
{
\r\n
  int N, M;
\r\n
  scanf(\"%d %d\", &N, &M);
\r\n
  long long ans = numeric_limits<long long>::max();
\r\n
  for (int i = 0; i < M; i++) {
\r\n
    int u, d;
\r\n
    scanf(\"%d %d\", &u, &d);
\r\n
    ans = min(ans, solve(u, d, N));
\r\n
  }
\r\n
  printf(\"%lldn\", ans);
\r\n
  return 0;
\r\n
}
\r\n
\r\n
\r\n
\r\n ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2905, '%e6%8b%9b%e8%81%98%e5%90%af%e4%ba%8b', '招聘启事', '2012-08-15 22:48:56', '2019-03-25 21:29:22', '      本站因发展需要,现急需文章编辑与美工人员若干名,有意者QQ1035136784联系。
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2906, 'detailed-explanation-of-the-string-classes-in-the-java', 'Java中的String类详解', '2012-08-14 19:43:24', '2019-03-25 21:29:22', '      Java字符串类(java.lang.String)是Java中使用最多的类,也是最为特殊的一个类,很多时候,我们对它既熟悉又陌生。
\r\n  一、从根本上认识java.lang.String类和String池
\r\n  首先,我建议先看看String类的源码实现,这是从本质上认识String类的根本出发点。从中可以看到:
\r\n  1、String类是final的,不可被继承。public final class String。
\r\n  2、String类是的本质是字符数组char[], 并且其值不可改变。private final charvalue[];
\r\n  然后打开String类的API文档,可以发现:
\r\n  3、String类对象有个特殊的创建的方式,就是直接指定比如String x ="abc","abc"就表示一个字符串对象。而x是"abc"对象的地址,也叫做"abc"对象的引用。
\r\n  4、String对象可以通过“+”串联。串联后会生成新的字符串。也可以通过concat()来串联,这个后面会讲述。
\r\n  6、Java运行时会维护一个String Pool(String池),JavaDoc翻译很模糊“字符串缓冲区”。String池用来存放运行时中产生的各种字符串,
\r\n  并且池中的字符串的内容不重复。而一般对象不存在这个缓冲池,并且创建的对象仅仅存在于方法的堆栈区。
\r\n  5、创建字符串的方式很多,归纳起来有三类:
\r\n  其一,使用new关键字创建字符串,比如String s1 = new String("abc");
\r\n  其二,直接指定。比如String s2 = "abc";
\r\n  其三,使用串联生成新的字符串。比如String s3 = "ab" + "c"; 
\r\n  二、String对象的创建
\r\n  String对象的创建也很讲究,关键是要明白其原理。
\r\n  原理1:当使用任何方式来创建一个字符串对象s时,Java运行时(运行中JVM)会拿着这个X在String池中找是否存在内容相同的字符串对象,如果不存在,则在池中创建一个字符串s,否则,不在池中添加。
\r\n  原理2:Java中,只要使用new关键字来创建对象,则一定会(在堆区或栈区)创建一个新的对象。
\r\n  原理3:使用直接指定或者使用纯字符串串联来创建String对象,则仅仅会检查维护String池中的字符串,池中没有就在池中创建一个,有则罢了!但绝不会在堆栈区再去创建该String对象。
\r\n  原理4:使用包含变量的表达式来创建String对象,则不仅会检查维护String池,而且还会在堆栈区创建一个String对象。
\r\n  另外,String的intern()方法是一个本地方法,定义为public native String intern(); intern()方法的价值在于让开发者能将注意力集中到String池上。当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(该对象由 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并且返回此 String 对象的引用。
\r\n  三、不可变类
\r\n  不可改变的字符串具有一个很大的优点:编译器可以把字符串设置为共享。 
\r\n  不可变类String有一个重要的优点-它们不会被共享引用。
\r\n  是这样的,JAVA为了提高效率,所以对于String类型进行了特别的处理---为string类型提供了串池 
\r\n  定义一个string类型的变量有两种方式: 
\r\n  string name= "tom "; 
\r\n  string name =new string( "tom ") 
\r\n  使用第一种方式的时候,就使用了串池, 
\r\n  使用第二中方式的时候,就是一种普通的声明对象的方式 
\r\n  如果你使用了第一种方式,那么当你在声明一个内容也是 "tom "的string时,它将使用串池里原来的那个内存,而不会重新分配内存,也就是说,string saname= "tom ",将会指向同一块内存 
\r\n  另外关于string类型是不可改变的问题: 
\r\n  string类型是不可改变的,也就是说,当你想改变一个string对象的时候,比如name= "madding " 
\r\n  那么虚拟机不会改变原来的对象,而是生成一个新的string对象,然后让name去指向它,如果原来的那个 "tom "没有任何对象去引用它,虚拟机的垃圾回收机制将接收它。 
\r\n  据说这样可以提高效率!!!
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2907, '%e5%ad%94%e4%b9%99%e5%b7%b1it%e7%89%88', '孔乙己IT版', '2012-08-14 19:31:51', '2019-03-25 21:29:22', '

\r\n       鲁镇的网吧的格局,是和别处不同的:都是当街一个曲尺形的大柜台,柜里面预备着热水和各色各样的饮料和酒。做工的人,傍午傍晚散了工,每每花五块钱,来通宵上网,还可以附送一碗酒,一边喝酒一边上网。——这是二十多年前的事,现在每晚要涨到十块钱,——靠柜外站着,热热的喝了休息;倘肯多花一块钱,便可以买一碟茴香豆,做下酒物了,如果 出到十几块钱,那就能买一样荤菜,但这些顾客,多是短衣帮,上网看的东西都是拿不上台面的,所以都是站着上网的,衙门一来,也好撒腿就跑,短衣帮大抵没有这样阔绰。只有穿长衫的,才踱进店面隔壁的房子里,要酒要菜,慢慢地一边坐喝,一边看着屏幕上那些说不出口的东西。
\r\n
\r\n   我 从十二岁起,便在镇口的咸亨网吧里当伙计,这个网吧比较大,除了给客人上网的服务,还有帮客人定制一些不三不四的工具的开发部门。一开始,掌柜说,样子太 傻,怕侍候不了长衫主顾,就在外面做点事罢。外面的短衣主顾,虽然容易说话,但唠唠叨叨缠夹不清的也很不少。他们往往亲自带着怀表,结帐的时候要看看网吧 有没有少算钟点,有的还亲自打电话到格林尼治天文台校对自己怀表有没有跑快了,然后才放心:在这严重兼督下,对计时器做手脚也很为难。所以过了几天,掌柜 又说我干不了这事。幸亏荐头的情面大,辞退不得,另一个原因也是我在巨软中国研究院做过几年码农,所以便改为专管写一些psp.net程序的一种无聊职务了。 
\r\n
\r\n   我从此便整天的站在柜台里,专管我的职务。虽然没有什么失职,但总觉得有些单调,有些无聊。掌柜是一副凶脸孔,主顾也没有好声气,教人活泼不得;只有孔乙己到店,才可以笑几声,所以至今还记得。 
\r\n
\r\n   孔乙己是站着上网而穿长衫的唯一的人。他身材很高大;青白脸色,皱纹间时常夹些伤痕;一部乱蓬蓬的花白的胡子。穿的虽然是长衫,可是又脏又破,似乎十多年没有补,也没有洗。他对人说话,总是满口之乎者也,教人半懂不懂的。因为他姓孔,别人便从描红纸上的上大人孔乙己这半懂不懂的话里,替他取下一个绰号,叫作孔乙己。孔乙己一到店,所有喝酒的人便都看着他笑,有的叫道,孔乙己,你脸上又添上新伤疤了!他不回答,对柜里说,上两个小时,要一碟茴香豆。便排出十九块钱。他们又故意的高声嚷道,你一定又偷了人家的东西了!孔乙己睁大眼睛说,你怎么这样凭空污人清白……”“什么清 白?我前天亲眼见你反编译了kernel32.dll,被鲍掌柜吊着打。孔乙己便涨红了脸,额上的青筋条条绽出,争辩道,借鉴不能算偷……借鉴!……科学家的事,能算偷么?接连 便是难懂的话,什么骆驼命名法是大写在前还是小写在前,什么“using各有几种用法之类,随口便抛出一句:你们这些人,要回家复习功课了,引得众人都哄笑起来:店内外充满了快活的空气。
\r\n
\r\n   听人家背地里谈论,孔乙己原来也读过书,还是NVPNCSE, 但终于没有进学,又不会营生;于是愈过愈穷,弄到将要讨饭了。幸而写得一手漂亮的代码,运行起来很快很强大,便接一些私活,换一碗饭吃。可惜他又有一样坏 脾气,便是摆着看过几本书的架子愤世嫉俗。坐不到几天,便在同事的代码里面挑刺,说这段不符合什么规矩原则,那段没有实现接口……搞得团队很紧张,经常延误工时。如是几次,叫他做事的人也没有了。孔乙己没有法,便免不了偶然做些入侵银行主机的事。但他在我们店里,品行却比别人都好,就是从不拖欠;虽然间或没有现钱,暂时记在粉板上,但不出一月,定然还清,从粉板上拭去了孔 乙己的名字。 
\r\n
\r\n   孔乙己喝过半碗酒,涨红的脸色渐渐复了原,旁人便又问道,孔乙己,你当真会编程么?孔乙己看着问他的人,显出不屑置辩的神气。他们便接着说道,你怎的连半个秀才也捞不到呢?孔乙己立刻显出颓唐不安模样,脸上笼上了一层灰色,嘴里说些话;这回可是全是指针堆之类,一些不懂了,随口便抛出一句:“你们这些人,要回家复习功课了,在这时候,众人也都哄笑起来:店内外充满了快活的空气。
\r\n
\r\n   在这些时候,我可以附和着笑,掌柜是决不责备的。而且掌柜见了孔乙己,也每每这样问他,引人发笑。孔乙己自己知道不能和他们谈天,便只好向 孩子说话。有一回对我说道,你写过程序么?我略略点一点头。他说,写过,……我便考你一考。茴香豆的茴字,怎样在屏幕上打印出来?我想,讨饭一样的人,也配考我么?便回过脸去,不再理会。孔乙己等了许久,很恳切的说道,不会罢?……我教给你,记着!这些模式应该记着。将来做掌柜的时候,写账要用。我暗想我和掌柜的等级还很远呢,而且我们掌柜也从不将茴香豆上账;又好笑,又不耐烦,懒懒的答他道,谁要你教,不是Console.WriteLine一个草头,然后再一个来回的回字么?孔乙己显出极高 兴的样子,将两个指头的长指甲敲着柜台,点头说,对呀对呀!……回字有四样写法,你知道么?你的这个办法不好,有很多冗余,万一有人写错了,也不好追查责任,我写给你看,你看我综合使用了模板方法模式、桥接模式、抽象工厂模式、通用数据库兼容模式,优美极了”:

\r\n

\r\n  我愈不耐烦了,努着嘴走远。写完后,孔乙己向掌柜的讨来一支烟,还想继续说些什么,见我毫不热心,便又叹一口气,显出极惋惜的样子。 
\r\n
\r\n   有几回,邻居孩子听得笑声,也赶热闹,围住了孔乙己。他便给他们吃茴香豆,一人一颗。孩子吃完豆,仍然不散,眼睛都望着碟子。孔乙己着了 慌,伸开五指将碟子罩住,弯腰下去说道,谁能告诉我一个TCP/IP数据包能容纳多少个字,这盘豆子就给谁。,孩子们你望我,我望你,有的伸出五个手指,有的伸出二个手指……孔乙己直起身又看一看豆,自己摇头说,不多不多!多乎哉?不多也。于是这一群孩子都在 笑声里走散了。 
\r\n
\r\n   孔乙己是这样的使人快活,可是没有他,别人也便这么过。 
\r\n
\r\n   有一天,大约是中秋前的两三天,掌柜正在慢慢的结账,取下粉板,忽然说,孔乙己长久没有来了。还欠十九块钱呢!我才也觉得他的确长久没有 来了。一个喝酒的人说道,他怎么会来?……他打折了腿了。掌柜说,哦!”“他总仍旧是那副看不起人的嘴脸。这一回,是自己发昏,竟然当街和别人争论汇编语言有几种数据类型。那些人,惹得起的么?”“后来怎么样?”“怎么样?先录口供,后来是打,打了大半夜,再打折了腿。”“后来呢?”“后来打折了腿了。”“打折了怎样呢?”“ 样?……谁晓得?许是死了。掌柜也不再问,仍然慢慢的算他的账。 
\r\n
\r\n   中秋之后,秋风是一天凉比一天,看看将近初冬;我整天的靠着火,也须穿上棉袄了。一天的下半天,没有一个顾客,我正合了眼坐着。忽然间听得 一个声音,上三个小时,要间包房。这声音虽然极低,却很耳熟。看时又全没有人。站起来向外一望,那孔乙己便在柜台下对了门槛坐着。他脸上黑而且瘦,已经不成样子; 穿一件破夹袄,盘着两腿,下面垫一个蒲包,用草绳在肩上挂住;见了我,又说道,上三个小时,要间包房。掌柜也伸出头去,一面说,孔乙己么?你还欠十九块钱呢! 孔乙己很颓唐的仰面答道,……下回还清罢。这一回是现钱,房间要干净,陪上网的要长得漂亮。掌柜仍然同平常一样,笑着对他说,孔乙己,你又惹事了!但他这回却不十分分辩,单说了一句不要取笑!”“取笑?你不惹事,怎么会打断腿?孔乙己低声说道,跌断,跌,跌……”他的眼色,很像恳求掌柜,不要再提。此时已经聚 集 了几个人,便和掌柜都笑了。我安排了房间,带他进去。他从破衣袋里摸出六块钱,放在我手里,见他满手是泥,原来他便用这手走来的。三个小时后,他上完网。 孔乙己在结帐的时候从来不和我们计较钟点,这次,我还多给他上了十分钟。这次他从包房里走出来,是满脸的惆怅,看到他的脸色,有人取笑道:孔乙己,德鲁伊升到几级了?,孔乙己答道:尽是MFC,服务器也没有使用AEAWEBLOGIC,升级模块里面一大堆冗余数据,玩这种东西丢人不丢人?””丢人?我亲眼看着你玩的,你又破解人家的DLL想偷代码了?,孔乙己立刻显出颓唐不安模样,脸上笼上了一层灰色:君子故穷,其言显富,皆等货色,何需窃乎。你们这些人,要回家复习功课了。便又在旁人的说笑声中,坐着用这手慢慢走去了。
\r\n
\r\n
\r\n   自此以后,又长久没有看见孔乙己。到了年关,掌柜取下粉板说,孔乙己还欠十九块钱呢!到第二年的端午,又说孔乙己还欠十九块钱呢!到中秋可是没有说,再到年关也没有看见他。 
\r\n
\r\n   我到现在终于没有见——大约孔乙己的确死了。

\r\n       文章转载自:http://www.cnblogs.com/kvspas/archive/2008/12/25/1361932.html#Feedback
\r\n  

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2908, 'null-and-the-difference', 'null与""的区别', '2012-08-14 19:27:38', '2019-03-25 21:29:22', '      让我们通过例子对 null 与 "" 的区别作一个详细的解释:\r\n

\r\n String str1 = null; str引用为空
\r\n String str2 = ""; str引用一个空串

\r\n

\r\n       也就是null没有分配空间,""分配了空间,因此str1还不是一个实例化的对象,而str2已经实例化。

\r\n

\r\n       注意因为null不是对象,""是对象。所以比较的时候必须是 if(str1==null){....}if(str2.equals("")){}

\r\n

\r\n       对象用equals比较,null用等号比较。因此,如果str1=null;下面的写法错误:
\r\n if(str1.equals("")||str1==null){
\r\n }

\r\n

\r\n       正确的写法是 if(str1==null||str1.equals("")){ //先判断是不是对象,如果是,再判断是不是空字符串
\r\n //...
\r\n } 

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2909, 'three-kingdoms-characters-long-jie-zhi-cao-cao', '三国杀人物详解之曹操', '2012-08-14 19:16:07', '2019-03-25 21:29:22', '

\r\n 三国杀曹操【魏国】

\r\n

\r\n \"三国杀曹操\"

\r\n

\r\n 武将名:曹操

\r\n

\r\n 称号:魏武帝

\r\n

\r\n 势力:魏国

\r\n

\r\n 生命:★★★★

\r\n

\r\n 武将技:

\r\n

\r\n 奸雄:你可以立即获得对你造成伤害的牌。

\r\n

\r\n 护驾:主公技,当你需要使用(或打出)一张【闪】时,你可以发动护驾。所有魏势力角色按行动顺序依次选择是否打出一张【闪】“提供”给你(视为由你使用或打出),直到有一名角色或没有任何角色决定如此做时为止。

\r\n

\r\n ★同一张牌的一次完整的结算中(包括因结算引发的其他事件)只能发动一次奸雄。

\r\n

\r\n [Q]【奸雄】技能是否在满足条件时必须发动?

\r\n

\r\n [A]【奸雄】不是锁定技,可以选择性发动。

\r\n

\r\n [Q]当锦囊牌对曹操造成伤害时,曹操获得哪张牌?

\r\n

\r\n [A]只获得相应的锦囊,例如曹操判定【闪电】受到伤害,可以将【闪电】收入手牌。

\r\n

\r\n [Q]角色A对角色B使用【借刀杀人】,要求B对曹操使用【杀】,若B使用了【杀】对曹操造成伤害,曹操获得哪张牌?

\r\n

\r\n [A]获得B使用的【杀】。

\r\n

\r\n [Q]角色发动武将技能对曹操造成伤害时,曹操拿哪张牌?

\r\n

\r\n [A]如果是被【刚烈】、【离间】、【雷击】等造成伤害,那么不能获得任何牌。如果是相关的技能消耗造成伤害,例如【流离】,【天香】等,则曹操获取伤害源打出或使用的相应牌。

\r\n

\r\n [Q]角色发动武器技能对曹操造成伤害,曹操获得哪张牌?

\r\n

\r\n [A]只获得相应的【杀】。

\r\n

\r\n 例如:曹操被其他角色发动【青龙偃月刀】的技能伤害,只能获得该角色使用的最后的一张【杀】;曹操被其他角色发动【贯石斧】的技能伤害,只能获得该 角色使用的那张【杀】,不能获得对方为了发动武器技能弃掉的牌;曹操被其他角色发动【丈八蛇矛】的技能伤害,可以获得该角色为了发动武器技能打出的两张手 牌。

\r\n

\r\n [Q]曹操进入濒死状态时,是否可以发动【奸雄】技能获得导致曹操进入濒死状态的牌?

\r\n

\r\n [A]不可以,除非曹操被救回。

\r\n

\r\n 例如:A角色对曹操使用【杀】,曹操受伤害进入濒死状态,如果没有角色对曹操使用【桃】,则曹操死亡,该【杀】进入弃牌堆。

\r\n

\r\n [Q]曹操发动【护驾】时,“魏”势力角色是否可以发动相关的武将或防具技能?

\r\n

\r\n [A]可以。例如甄姬可以发动【倾国】,“魏”势力角色可以发动【八卦阵】的技能进行判定。

\r\n

\r\n [Q]曹操发动【护驾】时,装备了【八卦阵】的“魏”势力角色可以发动几次【八卦阵】的技能?

\r\n

\r\n [A]曹操每次发动【护驾】,“魏”势力角色只能发动1次【八卦阵】的技能。

\r\n

\r\n [Q]曹操发动【护驾】时,装备了【八卦阵】的“魏”势力角色发动【八卦阵】的技能,判定牌为黑色,此时该角色是否可以从手中打出一张【闪】“提供”给曹操?

\r\n

\r\n [A]可以。

\r\n

\r\n [Q]吕布对曹操使用【杀】,曹操发动【护驾】,如果“魏”势力角色总共只“提供”了一张【闪】,如何结算?

\r\n

\r\n [A]若曹操此时自己再使用一张【闪】,则可以抵消吕布的【杀】;若曹操此时自己不能再使用一张【闪】,则受到该【杀】的伤害,“魏”势力角色“提供”的那张【闪】无效,不能收回。

\r\n

\r\n [Q]曹操受到连环传导的伤害时能否发动【奸雄】?

\r\n

\r\n [A]可以。

\r\n

\r\n [Q]有人使用【万箭齐发】,曹操发动【奸雄】技能后,小乔发动【天香】把伤害转移给曹操,曹操如何结算?

\r\n

\r\n [A]直接结算【天香】,同一张牌的一次完整的结算中(包括因结算引发的其他事件)只能发动一次奸雄。

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2910, 'ado%e8%af%a6%e8%a7%a3', 'ADO详解', '2012-08-14 19:07:43', '2019-03-25 21:29:22', '      ADO是ActiveX Data Object(ActiveX数据对象)的英文缩写,它是微软公司开发的数据库访问组件。
\r\n      ADO是一种既易于使用又可扩充的技术,用于实现对数据库的访问。
\r\n      它提供了供开发人员实时存取数据的能力。在数据库的应用中,使用ADO编写的应用程序可以存取在internet上的任何资源。总之,ADO是一项易于使用且可扩展的数据库访问技术。可以使用ADO编写紧凑建明的脚本,以便连接到与Open DataBase Connectivity(ODBC)兼容的数据库和与OLEDB兼容的数据源。
\r\n
\r\n      ADO组件又称为数据库访问组件,用于访问存储在数据库或其他数据表中的信息。ADO设计了许多环环相扣的继承对象,让开发人员可以轻松地操纵数据库,在ADO运行时继承子对象之间是相互影响的。
\r\n      ADO提供了一下7种对象:
\r\n      (1)Connection对象:提供对数据库的连接服务;
\r\n      (2)Command对象:定义对数据源操作的命令;
\r\n      (3)RecordSet对象:由数据库返回的记录集;
\r\n      (4)Fields对象:有数据库服务器返回的单一数据字段;
\r\n      (5)
Parameters对象:表示Command对象的参数;
\r\n      (6)Proerty对象:单独的一个Proerty对象提供属性功能;
\r\n      (7)Error对象:提供处理错误的功能。
\r\n      使用ADO对象可以建立和管理数据库的连接,按数据库服务器的要求获得数据,执行更新、删除、添加数据,获取ODBC错误信息等。
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2911, 'the-difference-between-define-and-typedef', 'typedef与#define的区别', '2012-08-14 19:06:13', '2019-03-25 21:29:22', '

\r\n 一、typedef的用法

\r\n

\r\n       在C/C++语言中,typedef常用来定义一个标识符及关键字的别名,它是语言编译过程的一部分,但它并不实际分配内存空间,实例像:

\r\n

\r\n typedef    int       INT;
\r\n typedef    int       ARRAY[10];
\r\n typedef   (int*)   pINT;

\r\n

\r\n typedef可以增强程序的可读性,以及标识符的灵活性,但它也有非直观性等缺点。

\r\n

\r\n  

\r\n

\r\n 二、#define的用法

\r\n

\r\n       #define为一宏定义语句,通常用它来定义常量(包括无参量与带参量),以及用来实现那些表面似和善、背后一长串的宏,它本身并不在编译过程中进行,而是在这之前(预处理过程)就已经完成了,但也因此难以发现潜在的错误及其它代码维护问题,它的实例像:

\r\n

\r\n #define   INT             int
\r\n #define   TRUE         1
\r\n #define   Add(a,b)     ((a)+(b));
\r\n #define   Loop_10    for (int i=0; i<10; i++)

\r\n

\r\n       在Scott MeyerEffective C++一书的条款1中有关于#define语句弊端的分析,以及好的替代方法,大家可参看。

\r\n

\r\n  

\r\n

\r\n 三、typedef#define的区别

\r\n

\r\n       以上的概念便也能基本清楚,typedef只是为了增加可读性而为标识符另起的新名称(仅仅只是个别名),而#define原本在C中是为了定义常量,到了C++constenuminline的出现使它也渐渐成为了起别名的工具。有时很容易搞不清楚与typedef两者到底该用哪个好,如#define INT int这样的语句,用typedef一样可以完成,用哪个好呢?我主张用typedef,因为在早期的许多C编译器中这条语句是非法的,只是现今的编译器又做了扩充。为了尽可能地兼容,一般都遵循#define可读的常量以及一些宏语句的任务,而typedef则常用来定义关键字、冗长的类型的别名。

\r\n

\r\n       宏定义只是简单的字符串代换(原地扩展),而typedef则不是原地扩展,它的新名字具有一定的封装性,以致于新命名的标识符具有更易定义变

\r\n

\r\n 量的功能。请看上面第一大点代码的第三行:

\r\n

\r\n typedef    (int*)      pINT;
\r\n 以及下面这行:
\r\n #define    pINT2    int*

\r\n

\r\n       效果相同?实则不同!实践中见差别:pINT a,b;的效果同int *a; int *b;表示定义了两个整型指针变量。而pINT2 a,b;的效果同int *a, b;表示定义了一个整型指针变量a和整型变量b即#define只是简单地字符串替换,而typedef则定义了一个新的类型。

\r\n

\r\n  
\r\n 四、typedef的四个用途和两个陷阱

\r\n

\r\n 用途一:
\r\n       定义一种类型的别名,而不只是简单的宏替换。可以用作同时声明指针型的多个对象。比如:
\r\n char*   pa,   pb;     //   这多数不符合我们的意图,它只声明了一个指向字符变量的指针,  
\r\n //  
和一个字符变量;
\r\n 以下则可行:
\r\n typedef   char*   PCHAR;     //   一般用大写
\r\n PCHAR   pa,   pb;                 //   可行,同时声明了两个指向字符变量的指针
\r\n 虽然:
\r\n char   *pa,   *pb;
\r\n 也可行,但相对来说没有用typedef的形式直观,尤其在需要大量指针的地方,typedef的方式更省事。
\r\n
\r\n 用途二:
\r\n       用在旧的C代码中(具体多旧没有查),帮助struct以前的代码中,声明struct新对象时,必须要带上struct,即形式为:   struct   结构名   对象名,如:
\r\n struct   tagPOINT1
\r\n {
\r\n         int   x;
\r\n         int   y;
\r\n };
\r\n struct   tagPOINT1   p1;  

\r\n
\r\n 而C++中,则可以直接写:结构名   对象名,即:
\r\n tagPOINT1   p1;
\r\n
\r\n 估计某人觉得经常多写一个struct太麻烦了,于是就发明了:
\r\n typedef   struct   tagPOINT
\r\n {
\r\n         int   x;
\r\n         int   y;
\r\n }POINT;
\r\n
\r\n POINT   p1;   //  
这样就比原来的方式少写了一个struct,比较省事,尤其在大量使用的时候
\r\n
\r\n 或许,在C++中,typedef的这种用途二不是很大,但是理解了它,对掌握以前的旧代码还是有帮助的,毕竟我们在项目中有可能会遇到较早些年代遗留下来的代码。
\r\n
\r\n 用途三:
\r\n       用typedef来定义与平台无关的类型。
\r\n 比如定义一个叫   REAL   的浮点类型,在目标平台一上,让它表示最高精度的类型为:
\r\n typedef   long   double   REAL;  
\r\n 在不支持   long   double   的平台二上,改为:
\r\n typedef   double   REAL;  
\r\n 在连   double   都不支持的平台三上,改为:
\r\n typedef   float   REAL;  
\r\n       也就是说,当跨平台时,只要改下typedef本身就行,不用对其他源码做任何修改。 标准库就广泛使用了这个技巧,比如size_t
\r\n       另外,因为typedef是定义了一种类型的新别名,不是简单的字符串替换,所以它比宏来得稳健(虽然用宏有时也可以完成以上的用途)。
\r\n
\r\n 用途四:
\r\n       为复杂的声明定义一个新的简单的别名。方法是:在原来的声明里逐步用别名替换一部分复杂声明,如此循环,把带变量名的部分留到最后替换,得到的就是原声明的最简化版。举例:
\r\n
\r\n 1.   原声明:int   *(*a[5])(int,   char*);
\r\n 变量名为a,直接用一个新别名pFun替换a就可以了:
\r\n typedef   int   *(*pFun)(int,   char*);  
\r\n 原声明的最简化版:
\r\n pFun   a[5];  
\r\n
\r\n 2.  
原声明:void   (*b[10])   (void   (*)());
\r\n 变量名为b,先替换右边部分括号里的,pFunParam为别名一:
\r\n typedef   void   (*pFunParam)();
\r\n 再替换左边的变量bpFunx为别名二:
\r\n typedef   void   (*pFunx)(pFunParam);
\r\n 原声明的最简化版:
\r\n pFunx   b[10];
\r\n
\r\n 3.  
原声明:doube(*)()   (*e)[9];  
\r\n 变量名为e,先替换左边部分,pFuny为别名一:
\r\n typedef   double(*pFuny)();
\r\n 再替换右边的变量epFunParamy为别名二
\r\n typedef   pFuny   (*pFunParamy)[9];
\r\n 原声明的最简化版:
\r\n pFunParamy   e;  
\r\n
\r\n       理解复杂声明可用的右左法则:从变量名看起,先往右,再往左,碰到一个圆括号就调转阅读的方向;括号内分析完就跳出括号,还是按先右后左的顺序,如此循环,直到整个声明分析完。举例:
\r\n int   (*func)(int   *p);
\r\n       首先找到变量名func,外面有一对圆括号,而且左边是一个*号,这说明func是一个指针;然后跳出这个圆括号,先看右边,又遇到圆括号,这说明(*func)是一个函数,所以func是一个指向这类函数的指针,即函数指针,这类函数具有int*类型的形参,返回值类型是int
\r\n int   (*func[5])(int   *);
\r\n      func
右边是一个[]运算符,说明func是具有5个元素的数组;func的左边有一个*,说明func的元素是指针(注意这里的*不是修饰func,而是修饰func[5]的,原因是[]运算符优先级比*高,func先跟[]结合)。跳出这个括号,看右边,又遇到圆括号,说明func数组的元素是函数类型的指针,它指向的函数具有int*类型的形参,返回值类型为int
\r\n
\r\n 也可以记住2个模式
\r\n type   (*)(....)函数指针  
\r\n type   (*)[]
数组指针  

\r\n ---------------------------------
\r\n
\r\n 陷阱一:
\r\n 记住,typedef是定义了一种类型的新别名,不同于宏,它不是简单的字符串替换。比如:
\r\n 先定义:
\r\n typedef   char*   PSTR;
\r\n 然后:
\r\n int   mystrcmp(const   PSTR,   const   PSTR);
\r\n
\r\n const   PSTR
实际上相当于const   char*吗?不是的,它实际上相当于char*   const
\r\n 原因在于const给予了整个指针本身以常量性,也就是形成了常量指针char*   const
\r\n 简单来说,记住consttypedef一起出现时,typedef不会是简单的字符串替换就行。
\r\n
\r\n 陷阱二:
\r\n typedef在语法上是一个存储类的关键字(如autoexternmutablestaticregister等一样),虽然它并不真正影响对象的存储特性,如:
\r\n typedef   static   int   INT2;   //不可行
\r\n 编译将失败,会提示指定了一个以上的存储类

\r\n

\r\n  

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2913, 'built-in-functions-in-c-inline-details', 'C++中内置函数(inline)详解', '2012-08-14 18:59:54', '2019-03-25 21:29:22', '
\r\n 内联函数简介:
\r\n       内联函数(inline function与一般的函数不同,不是在调用时发生控制转移,而是在编译阶段将函数体嵌入到每一个调用语句中
\r\n       内联函数(inline function)与编译器的工作息息相关编译器会将程序中出现内联函数的调用表达式用内联函数的函数体来替换
\r\n
\r\n  
\r\n
\r\n
\r\n
\r\n
\r\n Cpp代码示例1: 
\r\n /**
\r\n *在类里定义的成员函数会被隐含指定为内置函数
\r\n */  
\r\n #include "stdafx.h"
\r\n #include <iostream>
\r\n #include <string>
\r\n
\r\n using namespace std;
\r\n
\r\n class CStudent
\r\n {
\r\n public:
\r\n     void display()
\r\n     {
\r\n         cout<<"name:"<<name<<endl;
\r\n     }
\r\n     string name;
\r\n };
\r\n
\r\n int main(int argc, char* argv[])
\r\n {
\r\n     CStudent myStudent;
\r\n     myStudent.name="Erin";
\r\n     myStudent.display();
\r\n     return 0;
\r\n }

\r\n
\r\n Cpp代码示例2: 
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n /**
\r\n *类外定义的函数用inline指定为内置函数
\r\n */
\r\n
\r\n #include "stdafx.h"
\r\n #include <iostream>
\r\n #include <string>
\r\n
\r\n using namespace std;
\r\n
\r\n class CStudent
\r\n {
\r\n public:
\r\n     inline void display();
\r\n     string name;
\r\n };
\r\n
\r\n inline void CStudent::display()
\r\n {
\r\n     cout<<"name:"<<name<<endl;
\r\n }
\r\n
\r\n int main(int argc, char* argv[])
\r\n {
\r\n     CStudent myStudent;
\r\n     myStudent.name="Erin";
\r\n     myStudent.display();
\r\n     return 0;
\r\n }
\r\n
\r\n
\r\n
\r\n Cpp代码示例3: 
\r\n /**
\r\n *无内置函数
\r\n *既没有在类内定义函数,也没有用inline在类外定义函数
\r\n */
\r\n
\r\n #include "stdafx.h"
\r\n #include <iostream>
\r\n #include <string>
\r\n
\r\n using namespace std;
\r\n
\r\n class CStudent
\r\n {
\r\n public:
\r\n     void display();
\r\n     string name;
\r\n };
\r\n
\r\n void CStudent::display()
\r\n {
\r\n     cout<<"name:"<<name<<endl;
\r\n }
\r\n
\r\n int main(int argc, char* argv[])
\r\n {
\r\n     CStudent myStudent;
\r\n     myStudent.name="Erin";
\r\n     myStudent.display();
\r\n     return 0;
\r\n }

\r\n  
\r\n
\r\n 内联函数的优点:
\r\n
\r\n      首先来看函数调用的实质,其实是将程序执行转移到被调用函数所存放的内存地址,将函数执行完后,在返回到执行此函数前的地方。这种转移操作需要保护现场 (包括各种函数的参数的进栈操作),在被调用函数代码执行完后,再恢复现场。但是保护现场和恢复现场需要较大的资源开销。
\r\n
\r\n      特别是对于一些较小的调用函数来说(如上边代码中的display()函数),若是频繁调用,函数调用过程甚至可能比函数执行过程需要的系统资源更多。所以引入内联函数,可以让程序执行效率更高。
\r\n
\r\n  
\r\n
\r\n 内联函数的缺点:
\r\n
\r\n       如果调用内联函数的地方过多,也可能造成代码膨胀。毕竟,编译器会把内联函数的函数体嵌入到每一个调用了它的地方,重复地嵌入。
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2914, 'c-file-action-summary', 'C++文件操作总结', '2012-08-14 18:58:30', '2019-03-25 21:29:22', '一、ASCII 输出
\r\n      为了使用下面的方法, 你必须包含头文件<fstream.h>(笔者注:在标准C++中,已经使用<fstream>取代< fstream.h>,所有的C++标准头文件都是无后缀的)。这是 <iostream.h>的一个扩展集, 提供有缓冲的文件输入输出操作。事实上, <iostream.h> 已经被<fstream.h>包含了, 所以你不必包含所有这两个文件, 如果你想显式包含他们,那随便你。我们从文件操作类的设计开始, 我会讲解如何进行ASCII I/O操作。如果你猜是"fstream," 恭喜你答对了! 但这篇文章介绍的方法,我们分别使用"ifstream"和"ofstream" 来作输入输出。
\r\n      如果你用过标准控制台流"cin"和 "cout" 那现在的事情对你来说很简单。 我们现在开始讲输出部分,首先声明一个类对象。
\r\nofstream fout;
\r\n      这就可以了,不过你要打开一个文件的话, 必须像这样调用ofstream::open()。

\r\nfout.open("C:/Documents and Settings/Administrator/桌面/output.txt");
\r\n      你也可以把文件名作为构造参数来打开一个文件.
\r\nofstream fout("C:/Documents and Settings/Administrator/桌面/output.txt");
\r\n      这是我们使用的方法, 因为这样创建和打开一个文件看起来更简单. 顺便说一句, 如果你要打开的文件不存在,它会为你创建一个, 所以不用担心文件创建的问题. 现在就输出到文件,看起来和"cout"的操作很像。对不了解控制台输出"cout"的人, 这里有个例子。
\r\nint num = 247;
\r\nchar name[] = "www.xinvalue.com";
\r\nfout << "新价值网已经诞生了" << num << "天!n";
\r\nfout << "
新价值网的域名是: " << name << "n";
\r\n      现在保存文件,你必须关闭文件,或者回写文件缓冲. 文件关闭之后就不能再操作了, 所以只有在你不再操作这个文件的时候才调用它,它会自动保存文件。回写缓冲区会在保持文件打开的情况下保存文件, 所以只要有必要就使用它。 回写看起来像另一次输出, 然后调用方法关闭。像这样:
\r\nfout << flush;
\r\nfout.close();

\r\n      现在你用文本编辑器打开文件...
\r\n      很简单吧!
\r\n      现在继续文件输入, 需要一点技巧, 所以先确认你已经明白了流操作,对 "<<" 和">>" 比较熟悉了, 因为你接下来还要用到他们。
\r\n
\r\n二、ASCII 输入
\r\n      输入和"cin" 流很像. 和刚刚讨论的输出流很像, 但你要考虑几件事情。在我们开始复杂的内容之前, 先看一个文本:

\r\n新价值网
\r\n编程技术交流
\r\n软件源码共享
\r\n网站 设计开发

\r\n      为了打开这个文件,你必须创建一个in-stream对象,像这样:
\r\nifstream fin("
C:/Documents and Settings/Administrator/桌面/input.txt");
\r\n      现在读入前四行. 你还记得怎么用"<<" 操作符往流里插入变量和符号吧?好,在 "<<" (插入)操作符之后,是">>" (提取) 操作符. 使用方法是一样的.

\r\nchar sentence1[100];
\r\nchar sentence2[100];
\r\nchar sentence3[100];
\r\nchar sentence4[100];
\r\nfin >> sentence1;
\r\nfin >> sentence2;
\r\nfin >> sentence3;
\r\nfin >> sentence4;

\r\n      它是如何运作的呢? 文件的每个空白之后, ">>" 操作符会停止读取内容, 直到遇到另一个>>操作符. 因为我们读取的每一行都被换行符分割开(是空白字符), ">>" 操作符只把这一行的内容读入变量。但是,可别忘了文件的最后一行。
\r\n网站 设计开发
\r\n     
如果你想把整行读入一个char数组, 我们没办法用">>"操作符,因为每个单词之间的空格(空白字符)会中止文件的读取。
\r\n      我们想包含整个句子, "
网站 设计开发" 但是因为空白, 现在它只包含了"网站".
\r\n      很明显, 肯定有读取整行的方法, 它就是getline()。这就是我们要做的。
\r\nfin.getline(sentence1, 100);

\r\nfin.getline(sentence2, 100);
\r\nfin.getline(sentence3, 100);
\r\nfin.getline(sentence4, 100);
\r\n      这是函数参数. 第一个参数显然是用来接受的char数组. 第二个参数是在遇到换行符之前,数组允许接受的最大元素数量. 现在我们得到了想要的结果:“网站 设计开发”。
\r\n      你应该已经知道如何读取和写入ASCII文件了。但我们还不能罢休,因为二进制文件还在等着我们。
\r\n
\r\n三、二进制输入输出
\r\n      二进制文件会复杂一点, 但还是很简单的。 首先你要注意我们不再使用插入和提取操作符(笔者注:<< 和 >> 操作符). 你可以这么做,但它不会用二进制方式读写。你必须使用read() 和write() 方法读取和写入二进制文件. 创建一个二进制文件, 看下一行。
\r\nofstream fout("
C:/Documents and Settings/Administrator/桌面/file.dat", ios::binary);
\r\n      这会以二进制方式打开文件, 而不是默认的ASCII模式。首先从写入文件开始。函数write() 有两个参数。 第一个是指向对象的char类型的指针, 第二个是对象的大小(笔者注:字节数)。 为了说明,看例子。
\r\nint number = 30;
\r\nfout.write((char *)(&number), sizeof(number));

\r\n      第一个参数写做"(char *)(&number)". 这是把一个整型变量转为char *指针。如果你不理解,可以立刻翻阅C++的书籍,如果有必要的话。第二个参数写作"sizeof(number)"。sizeof() 返回对象大小的字节数. 就是这样!
\r\n      二进制文件最好的地方是可以在一行把一个结构写入文件。 如果说,你的结构有12个不同的成员。 用ASCII文件,你不得不每次一条的写入所有成员。 但二进制文件替你做好了。 看这个。
\r\nstruct OBJECT {
\r\nint number;
\r\nchar letter;
\r\n} obj;
\r\nobj.number = 15;
\r\nobj.letter = ‘M’;
\r\nfout.write((char *)(&obj), sizeof(obj));
\r\n     
这样就写入了整个结构! 接下来是输入. 输入也很简单,因为read()函数的参数和 write()是完全一样的, 使用方法也相同。
\r\nifstream fin("
C:/Documents and Settings/Administrator/桌面/file.dat", ios::binary);
\r\nfin.read((char *)(&obj), sizeof(obj));

\r\n      我不多解释用法, 因为它和write()是完全相同的。二进制文件比ASCII文件简单, 但有个缺点是无法用文本编辑器编辑。 接着, 我解释一下ifstream 和ofstream 对象的其他一些方法作为结束.
\r\n
\r\n四、更多方法
\r\n      我已经解释了ASCII文件和二进制文件, 这里是一些没有提及的底层方法。
\r\n
\r\n检查文件
\r\n      你已经学会了open()close() 方法, 不过这里还有其它你可能用到的方法。
\r\n      方法good() 返回一个布尔值,表示文件打开是否正确。
\r\n      类似的,bad() 返回一个布尔值表示文件打开是否错误。 如果出错,就不要继续进一步的操作了。
\r\n      最后一个检查的方法是fail(), 和bad()有点相似, 但没那么严重。
\r\n
\r\n读文件
\r\n      方法get() 每次返回一个字符。
\r\n      方法ignore(int,char) 跳过一定数量的某个字符, 但你必须传给它两个参数。第一个是需要跳过的字符数。 第二个是一个字符, 当遇到的时候就会停止。 例子,
\r\nfin.ignore(100, ‘/n’);
\r\n会跳过100个字符,或者不足100的时候,跳过所有之前的字符,包括 ‘/n’。
\r\n       方法peek() 返回文件中的下一个字符, 但并不实际读取它。所以如果你用peek() 查看下一个字符, 用get() 在peek()之后读取,会得到同一个字符, 然后移动文件计数器。
\r\n方法putback(char) 输入字符, 一次一个到流中。我没有见到过它的使用,但这个函数确实存在。
\r\n
\r\n写文件
\r\n只有一个你可能会关注的方法?那就是 put(char), 它每次向输出流中写入一个字符。
\r\n
\r\n打开文件
\r\n当我们用这样的语法打开二进制文件:

\r\nofstream fout("C:/Documents and Settings/Administrator/桌面/file.dat", ios::binary);
\r\n      "ios::binary"是你提供的打开选项的额外标志. 默认的, 文件以ASCII方式打开, 不存在则创建, 存在就覆盖. 这里有些额外的标志用来改变选项。
\r\nios::app 添加到文件尾
\r\nios::ate 把文件标志放在末尾而非起始。
\r\nios::trunc 默认. 截断并覆写文件。
\r\nios::nocreate 文件不存在也不创建。
\r\nios::noreplace 文件存在则失败。
\r\n
\r\n文件状态
\r\n      我用过的唯一一个状态函数是eof(), 它返回是否标志已经到了文件末尾。 我主要用在循环中。 例如, 这个代码断统计小写‘e’ 在文件中出现的次数。
\r\nifstream fin("
C:/Documents and Settings/Administrator/桌面/file.txt");
\r\nchar ch;
\r\nint counter;
\r\nwhile (!fin.eof()) {
\r\nch = fin.get();
\r\nif (ch == ‘e’) counter++;
\r\n}
\r\nfin.close();

\r\n      我从未用过这里没有提到的其他方法。 还有很多方法,但是他们很少被使用。参考C++书籍或者文件流的帮助文档来了解其他的方法。
\r\n
\r\n结论
\r\n      你应该已经掌握了如何使用ASCII文件和二进制文件。有很多方法可以帮你实现输入输出,尽管很少有人使用他们。我知道很多人不熟悉文件I/O操作,我希望这篇文章对你有所帮助。 每个人都应该知道. 文件I/O还有很多显而易见的方法,例如包含文件 <stdio.h>. 我更喜欢用流是因为他们更简单。 祝所有读了这篇文章的人好运, 也许以后我还会为你们写些东西。
\r\n
\r\n无论读写都要包含<fstream>头文件
\r\n      读:从外部文件中将数据读到程序中来处理
\r\n      对于程序来说,是从外部读入数据,因此定义输入流,即定义输入流对象:ifsteam infile,infile就是输入流对象。
\r\n      这个对象当中存放即将从文件读入的数据流。假设有名字为myfile.txt的文件,存有两行数字数据,具体方法:
\r\nint a,b;
\r\nifstream infile;
\r\ninfile.open("myfile.txt");      //注意文件的路径
\r\ninfile>>a>>b;                   //两行数据可以连续读出到变量里
\r\ninfile.close()

\r\n
\r\n      如果是个很大的多行存储的文本型文件可以这么读:
\r\nchar buf[1024];                //临时保存读取出来的文件内容
\r\nstring message;
\r\nifstream infile;
\r\ninfile.open("myfile.js");
\r\nif(infile.is_open())          //文件打开成功,说明曾经写入过东西
\r\n{
\r\n while(infile.good() && !infile.eof())
\r\n {
\r\n   memset(buf,0,1024);
\r\n   infile.getline(buf,1204);
\r\n   message = buf;
\r\n   ......                     //这里可能对message做一些操作
\r\n   cout<<message<<endl;
\r\n }
\r\n infile.close();
\r\n}

\r\n
\r\n      写:将程序中处理后的数据写到文件当中
\r\n对程序来说是将数据写出去,即数据离开程序,因此定义输出流对象ofstream outfile,outfile就是输出流对象,这个对象用来存放将要写到文件当中的数据。具体做法:
\r\nofstream outfile;
\r\noutfile.open("myfile.bat");  //myfile.bat是存放数据的文件名
\r\nif(outfile.is_open())
\r\n{
\r\n  outfile<<message<<endl;    //message是程序中处理的数据
\r\n  outfile.close();
\r\n}
\r\nelse
\r\n{
\r\n  cout<<"不能打开文件!"<<endl;
\r\n}

\r\n
\r\nc++对文件的读写操作的例子
\r\n/*从键盘读入一行字符,把其中的字母依次放在磁盘文件fa2.dat中,再把它从磁盘文件读入程序,将其中的小写字母改成大写字母,再存入磁盘fa3.dat中*/
\r\n#i nclude<fstream>
\r\n#i nclude<iostream>
\r\n#i nclude<cmath>
\r\nusing namespace std;
\r\n//从键盘上读取字符的函数
\r\n void read_save(){
\r\n      char c[80];
\r\n      ofstream outfile("f1.dat");//以输出方工打开文件
\r\n      if(!outfile){
\r\n                   cerr<<"open error!"<<endl;//注意是用的是cerr
\r\n                   exit(1);
\r\n                   }
\r\n          cin.getline(c,80);//从键盘读入一行字符
\r\n          for(int i=0;c[i]!=0;i++) //对字符一个一个的处理,直到遇到'/0'为止
\r\n                if(c[i]>=65&&c[i]<=90||c[i]>=97&&c[i]<=122){//保证输入的字符是字符
\r\n                   outfile.put(c[i]);//将字母字符存入磁盘文件
\r\n                   cout<<c[i]<<"";
\r\n                   }
\r\n                   cout<<endl;
\r\n                   outfile.close();
\r\n                   }
\r\n void creat_data(){
\r\n      char ch;
\r\n      ifstream infile("f1.dat",ios::in);//以输入的方式打开文件
\r\n      if(!infile){
\r\n                  cerr<<"open error!"<<endl;
\r\n                  exit(1);
\r\n                  }
\r\n    ofstream outfile("f3.dat");//定义输出流f3.dat文件
\r\n    if(!outfile){
\r\n                 cerr<<"open error!"<<endl;
\r\n                 exit(1);
\r\n                 }
\r\n     while(infile.get(ch)){//当读取字符成功时
\r\n     if(ch<=122&&ch>=97)
\r\n     ch=ch-32;
\r\n     outfile.put(ch);
\r\n     cout<<ch;
\r\n     }
\r\n     cout<<endl;
\r\n     infile.close();
\r\n     outfile.close();
\r\n     }
\r\n     int main(){
\r\n         read_save();
\r\n         creat_data();
\r\n        system("pause");
\r\n         return 0;
\r\n         }

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2915, 'use-the-history-object-url', '利用history对象处理URL', '2012-08-14 18:56:50', '2019-03-25 21:29:22', '    history的属性:
\r\n    length:获取历史列表中的元素数目。
\r\n    例子

\r\n    history的方法:
\r\n      back()
从历史列表中装入前一个 URL。
\r\n      forward()从历史列表中装入下一个 URL。
\r\n      go()从历史列表中装入URL。
\r\n      其中go(-1)back(),go(1)forward()的作用分别相同。
\r\n      说明:

\r\n      为安全起见,history 对象并不给出浏览器历史的实际 URL。该对象只提供了通过 back, forwardgo 方法在浏览器历史中导航的功能。浏览器历史中的特定文档可以由与当前页面相对的索引值代表。例如,指定 -1 作为 go 方法的参数和单击“后退”按钮一样。
\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2916, 'document-detailed-analysis', 'document对象详细剖析', '2012-08-14 18:53:23', '2019-03-25 21:29:22', '      意义:代表给定浏览器窗口中的 HTML 文档。
\r\n      属性:
 
\r\n         activeElement获取当父document拥有焦点时获得焦点的对象。
\r\n      aLinkColor
:设置或获取元素中所有激活链接的颜色。
\r\n      
bgColor:设置或获取表明对象后面的背景颜色的值(
不赞成)
\r\n      
chardet:设置或获取用于解码对象的字符集。
\r\n      cookie:设置或获取cookie的字符串值。
\r\n      defaultCharset:从当前区域语言中获取默认字符集。
\r\n      desginMode:设置或获取表明文档是否可被编辑的值。
\r\n      dir:设置或获取表名对象的阅读顺序的值。
\r\n      doctype:获取与当前文档关联的文档类型声明。
\r\n      documentElement:获取文档的根节点引用。
\r\n      chardet:设置或获取用于解码对象的字符集。
\r\n      chardet:设置或获取文档的安全域名。
\r\n      expando:设置或获取是否可在对象内创建任意变量的值
\r\n      fgColor:设置或获取文档的前景(文本)颜色。
\r\n      chardet:设置或获取用于解码对象的字符集。
\r\n      fileCreateData:获取文件创建的日期。
\r\n      fileModifiedData:获取文件上次修改的日期。
\r\n      fileSize:获取文件大小。
\r\n      implementation:获取当前文档的implementation对象。
\r\n      lastModified:获取上次修改的日期,如果页面提供的话。
\r\n      linkColor:设置或获取对象文档链接的颜色。
\r\n      parentWindow:获取容器对象所在的窗口引用。
\r\n      protocol:设置或获取url的协议部分。
\r\n      readyState:获取表明对象当前状态的值。
\r\n      referrer:获取将用户引入当前页面的位置url。
\r\n      uniqueID:获取为对象生成的唯一标识符。
\r\n      URL:设置或获取当前文档的URL。
\r\n      URLUnencoded:获取当前文档的URL,去掉所有文档编码。
\r\n      vLinkColor:设置或获取用户已访问过URL颜色。
\r\n      XMLDocument:获取由对象引出的XML文档对象模型(COM)的引用。
\r\n      XSLDocument:获取对XSL文档的顶层节点的引用。
\r\n
\r\n       集合
\r\n       all
:返回对象所包含的元素集合的引用。 
\r\n
\r\n       anchors:获取所有带有 name 和/或 id 属性的a对象的集合。此集合中的对象以 HTML源顺序排列。 
\r\n
\r\n       applets:获取文档中所有 applet 对象的集合。 
\r\n
\r\n       childNodes:获取作为指定对象直接后代的 HTML 元素和 TextNode 对象的集合。 
\r\n
\r\n       embeds:获取文档中所有 embed 对象的集合。 
\r\n
\r\n       forms:获取以源顺序排列的文档中所有 form 对象的集合。 
\r\n
\r\n       frames:获取给定文档定义或与给定窗口关联的文档定义的所有 window 对象的集合。 
\r\n
\r\n       images:获取以源顺序排列的文档中所有 img 对象的集合。 
\r\n
\r\n       links:获取文档中所有指定了 HREF 属性的 a 对象和所有 area 对象的集合。 
\r\n
\r\n       namespaces:获取 namespace 对象的集合。 
\r\n
\r\n       scripts:获取文档中所有 script 对象的集合。 
\r\n
\r\n       styleSheets:获取代表与文档中每个 link 或 style 对象的实例相对应的样式表的 styleSheet 对象的集合。 
\r\n       事件

\r\n
\r\n       onactivate:当对象设置为活动元素时触发。 
\r\n
\r\n       onbeforeactivate:对象要被设置为当前元素前立即触发。 
\r\n
\r\n       onbeforecut:当选中区从文档中删除之前在源对象触发。 
\r\n
\r\n       onbeforedeactivate:在 activeElement 从当前对象变为父文档其它对象之前立即触发。 
\r\n
\r\n       onbeforeeditfocus:在包含于可编辑元素内的对象进入用户界面激活状态前或可编辑容器变成控件选中区前触发。 
\r\n
\r\n       onbeforepaste:在选中区从系统剪贴板粘贴到文档前在目标对象上触发。 
\r\n
\r\n       onclick:在用户用鼠标左键单击对象时触发。 
\r\n
\r\n       oncontextmenu:在用户使用鼠标右键单击客户区打开上下文菜单时触发。 
\r\n
\r\n       oncontrolselect:当用户将要对该对象制作一个控件选中区时触发。 
\r\n
\r\n       oncut:当对象或选中区从文档中删除并添加到系统剪贴板上时在源元素上触发。 
\r\n
\r\n       ondblclick:当用户双击对象时触发。 
\r\n
\r\n       ondeactivate:当 activeElement 从当前对象变为父文档其它对象时触发。 
\r\n
\r\n       ondrag:当进行拖曳操作时在源对象上持续触发。 
\r\n
\r\n       ondragend:当用户在拖曳操作结束后释放鼠标时在源对象上触发。 
\r\n
\r\n       ondragenter:当用户拖曳对象到一个合法拖曳目标时在目标元素上触发。 
\r\n
\r\n       ondragleave:当用户在拖曳操作过程中将鼠标移出合法拖曳目标时在目标对象上触发。 
\r\n
\r\n        ondragover:当用户拖曳对象划过合法拖曳目标时持续在目标元素上触发。 
\r\n
\r\n        ondragstart:当用户开始拖曳文本选中区或选中对象时在源对象上触发。 
\r\n
\r\n        ondrop:当鼠标按钮在拖曳操作过程中释放时在目标对象上触发。 
\r\n
\r\n        onfocusin:当元素将要被设置为焦点之前触发。 
\r\n
\r\n        onfocusout:在移动焦点到其它元素之后立即触发于当前拥有焦点的元素上触发。 
\r\n
\r\n        onhelp:当用户在浏览器为当前窗口时按 F1 键时触发。 
\r\n
\r\n        onkeydown:当用户按下键盘按键时触发。 
\r\n
\r\n        onkeypress:当用户按下字面键时触发。 
\r\n
\r\n        onkeyup:当用户释放键盘按键时触发。 
\r\n
\r\n        onmousedown:当用户用任何鼠标按钮单击对象时触发。 
\r\n
\r\n        onmousemove:当用户将鼠标划过对象时触发。 
\r\n
\r\n        onmouseout:当用户将鼠标指针移出对象边界时触发。 
\r\n
\r\n        onmouseover:当用户将鼠标指针移动到对象内时触发。 
\r\n
\r\n        onmouseup:当用户在鼠标位于对象之上时释放鼠标按钮时触发。 
\r\n
\r\n        onmousewheel:当鼠标滚轮按钮旋转时触发。 
\r\n
\r\n        onmove:当对象移动时触发。 
\r\n
\r\n        onmoveend:当对象停止移动时触发。 
\r\n
\r\n        onmovestart:当对象开始移动时触发。 
\r\n
\r\n        onpaste:当用户粘贴数据以便从系统剪贴板向文档传送数据时在目标对象上触发。 
\r\n
\r\n        onpropertychange:当在对象上发生对象上发生属性更改时触发。 
\r\n
\r\n        onreadystatechange:当对象状态变更时触发。 
\r\n
\r\n        onresizeend:当用户更改完控件选中区中对象的尺寸时触发。 
\r\n
\r\n        onresizestart:当用户开始更改控件选中区中对象的尺寸时触发。 
\r\n
\r\n        onselectionchange:当文档的选中状态改变时触发。 
\r\n
\r\n        onstop:当用户单击停止按钮或离开 Web 页面时触发。 
\r\n        方法

\r\n
\r\n        attachEvent:将指定函数绑定到事件,以便每当该事件在对象上触发时都调用该函数。 
\r\n
\r\n        clear:目前尚未支持。 
\r\n
\r\n        close:关闭输出流并强制将数据发送到显示。 
\r\n
\r\n        createAttribute:以指定名称创建 attribute 对象。 
\r\n
\r\n        createComment:以指定数据创建 comment 对象。 
\r\n
\r\n        createDocumentFragment:创建一个新文档。 
\r\n
\r\n        createElement:为指定标签创建一个元素的实例。 
\r\n
\r\n        createEventObject:生成当使用 fireEvent 方法时用于传递事件相关信息的 event 对象。 
\r\n
\r\n        createStyleSheet:为文档创建样式表。 
\r\n
\r\n        createTextNode:从指定值中创建文本字符串。 
\r\n
\r\n        detachEvent:从事件中取消指定函数的绑定,这样当事件触发时函数就不会收到通知了。 
\r\n
\r\n        elementFromPoint:返回指定 x 和 y 坐标的元素。 
\r\n
\r\n        execCommand:在当前文档、当前选中区或给定范围上执行命令。 
\r\n
\r\n        focus:使得元素得到焦点并执行由 onfocus 事件指定的代码。 
\r\n
\r\n        getElementById:获取对 ID 标签属性为指定值的第一个对象的引用。 
\r\n
\r\n        getElementsByName:根据 NAME 标签属性的值获取对象的集合。 
\r\n
\r\n        getElementsByTagName:获取基于指定元素名称的对象集合。 
\r\n
\r\n        hasFocus:获取表明对象目前是否拥有焦点的值。 
\r\n
\r\n        mergeAttributes:复制所有读/写标签属性到指定元素。 
\r\n
\r\n        open:此方法以两种方式工作。该方法打开一个文档用于收集 write 和 writeln 方法的输出。在这种情况下,只使用前两个参数 url 和 name。若指定了附加参数,此方法将打开一个窗口,这与 window 对象的 window.open 方法相同。 
\r\n
\r\n        queryCommandEnabled:返回表明指定命令是否可于给定文档当前状态下使用                execCommand 命令成功执行的 Boolean 值。 
\r\n
\r\n        queryCommandIndeterm:返回表明指定命令是否处于模糊状态的 Boolean 值。 
\r\n
\r\n        queryCommandState:返回表明命令当前状态的 Boolean 值。 
\r\n
\r\n        queryCommandSupported:返回表明当前命令是否在当前区域上支持的 Boolean 值。 
\r\n
\r\n        queryCommandValue:返回文档、范围或当前选中区对于给定命令的当前值。 
\r\n
\r\n        recalc:重新计算当前文档中的全部动态属性。 
\r\n
\r\n        releaseCapture:释放当前文档中对象的鼠标捕捉。 
\r\n
\r\n        setActive:设置对象为当前对象而不将对象置为焦点。 
\r\n
\r\n        write:在指定窗口的文档中写入一个或多个 HTML 表达式。 
\r\n
\r\n        writeln:在指定窗口的文档中写入一个或多个 HTML 表达式,后面追加一个换行符。 
\r\n        对象

\r\n
\r\n        BODY
\r\n        body
:指定文档主体的开始和结束。 
\r\n
\r\n        implementation:包含了关于对象支持的模块信息。 
\r\n
\r\n        location:包含关于当前 URL 的信息。 
\r\n
\r\n        selection:代表了当前激活选中区,即高亮文本块,和/或文当中用户可执行某些操作的其它元素。 
\r\n
\r\n        TITLE
\r\n        title:包含文档的标题。 
\r\n  
   样式
\r\n     compatMode:设置或获取表明此对象是否应用标准兼容模式的值。
\r\n     休息一下吧!
\r\n
\r\n
\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2919, 'detailed-explanation-of-out-and-ref-in-c', 'C#中ref和out详解', '2012-08-14 16:54:02', '2019-03-25 21:29:22', '

\r\n   ref是传递参数的地址,out是返回值,两者有一定的相同之处,不过也有不同点。

\r\n

\r\n   - 使用ref前必须对变量赋值,out不用。

\r\n

\r\n   - out的函数会清空变量,即使变量已经赋值也不行,退出函数时所有out引用的变量都要赋值,ref引用的可以修改,也可以不修改。

\r\n

\r\n   区别可以参看下面的代码:

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n      using System;
\r\n   class TestApp
\r\n   {
\r\n   static void outTest(out int x, out int y)
\r\n   {//离开这个函数前,必须对x和y赋值,否则会报错。
\r\n   //y = x;
\r\n   //上面这行会报错,因为使用了out后,x和y都清空了,需要重新赋值,即使调用函数前赋过值也不行
\r\n   x = 1;
\r\n   y = 2;
\r\n   }
\r\n   static void refTest(ref int x, ref int y)
\r\n   {
\r\n   x = 1;
\r\n   y = x;
\r\n   }
\r\n   public static void Main()
\r\n   {
\r\n   //out test
\r\n   int a,b;
\r\n   //out使用前,变量可以不赋值
\r\n   outTest(out a, out b);
\r\n   Console.WriteLine("a={0};b={1}",a,b);
\r\n   int c=11,d=22;
\r\n   outTest(out c, out d);
\r\n   Console.WriteLine("c={0};d={1}",c,d);
\r\n   //ref test
\r\n   int m,n;
\r\n   //refTest(ref m, ref n);
\r\n   //上面这行会出错,ref使用前,变量必须赋值
\r\n   int o=11,p=22;
\r\n   refTest(ref o, ref p);
\r\n   Console.WriteLine("o={0};p={1}",o,p);
\r\n   }
\r\n   
\r\n

\r\n
\r\n     详解:

\r\n

\r\n   ref和out的区别在C# 中,既可以通过值也可以通过引用传递参数。通过引用传递参数允许函数成员更改参数的值,并保持该更改。若要通过引用传递参数, 可使用ref或out关键字。ref和out这两个关键字都能够提供相似的功效,其作用也很像C中的指针变量。它们的区别是:

\r\n

\r\n   1、使用ref型参数时,传入的参数必须先被初始化。对out而言,必须在方法中对其完成初始化。

\r\n

\r\n   2、使用ref和out时,在方法的参数和执行方法时,都要加Ref或Out关键字。以满足匹配。

\r\n

\r\n   3、out适合用在需要retrun多个返回值的地方,而ref则用在需要被调用的方法修改调用者的引用的时候。

\r\n

\r\n   注:在C#中,方法的参数传递有四种类型:传值(by value)传址(by reference)输出参数(by output)数组参数(by array)传值参数无需额外的修饰符,传址参数需要修饰符ref,输出参数需要修饰符out,数组参数需要修饰符params。传值参数在方法调用过 程中如果改变了参数的值,那么传入方法的参数在方法调用完成以后并不因此而改变,而是保留原来传入时的值。传址参数恰恰相反,如果方法调用过程改变了参数 的值,那么传入方法的参数在调用完成以后也随之改变。实际上从名称上我们可以清楚地看出两者的含义--传值参数传递的是调用参数的一份拷贝,而传址参数传 递的是调用参数的内存地址,该参数在方法内外指向的是同一个存储位置。

\r\n

\r\n   方法参数上的 ref 方法参数关键字使方法引用传递到方法的同一个变量。当控制传递回调用方法时,在方法中对参数所做的任何更改都将反映在该变量中。

\r\n

\r\n   若要使用 ref 参数,必须将参数作为 ref 参数显式传递到方法。ref 参数的值被传递到 ref 参数。

\r\n

\r\n   传递到 ref 参数的参数必须最先初始化。将此方法与 out 参数相比,后者的参数在传递到 out 参数之前不必显式初始化。

\r\n

\r\n   属性不是变量,不能作为 ref 参数传递。

\r\n

\r\n   如果两种方法的声明仅在它们对 ref 的使用方面不同,则将出现重载。但是,无法定义仅在 ref 和 out 方面不同的重载。

\r\n

\r\n   方法参数上的 out 方法参数关键字使方法引用传递到方法的同一个变量。当控制传递回调用方法时,在方法中对参数所做的任何更改都将反映在该变量中。

\r\n

\r\n   当希望方法返回多个值时,声明 out 方法非常有用。使用 out 参数的方法仍然可以返回一个值。一个方法可以有一个以上的 out 参数。

\r\n

\r\n   若要使用 out 参数,必须将参数作为 out 参数显式传递到方法。out 参数的值不会传递到 out 参数。

\r\n

\r\n   不必初始化作为 out 参数传递的变量。然而,必须在方法返回之前为 out 参数赋值。

\r\n

\r\n   属性不是变量,不能作为 out 参数传递。

\r\n

\r\n   网上有很多文章说ref 只传值,out传地址等等这种说法,好像不是非常的准确。以下是我做的实例代码,大家可以去试试:

\r\n\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n     using System;
\r\n   using System.Windows.Forms;
\r\n   public class Test
\r\n   {
\r\n   public static void Main()
\r\n   {
\r\n   cmdOut_Click();
\r\n   }
\r\n   public static int RefValue(int i, ref int j)
\r\n   {
\r\n   int k = j;
\r\n   j = 222;
\r\n   return i + k;
\r\n   }
\r\n   public static int OutValue(int i, out int j)
\r\n   {
\r\n   j = 222;
\r\n   return i + j;
\r\n   }
\r\n   private static void cmdRef_Click()
\r\n   {
\r\n   int m = 0;
\r\n   MessageBox.Show(RefValue(1, ref m).ToString());
\r\n   MessageBox.Show(m.ToString());
\r\n   }
\r\n   private static void cmdOut_Click()
\r\n   {
\r\n   int m;
\r\n   MessageBox.Show(OutValue(1, out m).ToString());
\r\n   MessageBox.Show(m.ToString());
\r\n   }
\r\n   }
\r\n

\r\n  

\r\n

\r\n  

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2920, 'asp-vulnerability-and-security-maintenance', 'ASP的漏洞与安全维护', '2012-08-14 16:46:00', '2019-03-25 21:29:22', '      网站建好后,如果不能正确配置网站的安全设置,不但无法保证ASP网站数据和程序的安全,而且也会影响网站的正常使用,所以,网站维护至关重要。以下是笔者整理的一些解决方案。
\r\n1.通过权限设置维护网站安全 
\r\n      (1)为提高网站安全性,可以通过NTFS访问保护ASP应用程序文件。NTFS权限Web服务器安全性的基础,它定义了一个或一组用户访问文件和目录的不同级别。
\r\n      (2)可以通过配置Web服务器的权限来限制所有用户查看、运行和操作ASP页的方式。不同与NTFS的权限控制方式,Web服务器权限应用于所有用户,并且不区分用户账号的类型。
\r\n      (3)可以设置有效地Windows NT(例如Windows XP)账号和密码,当用户试图访问被限制的内容时,Web服务器将进行身份验证,检查用户是否拥有有效的Windows NT(例如Windows XP)账号和密码。
\r\n      (4)可以使用客户端资格登陆控制用户对ASP应用程序的访问。客户资格是包含用户身份信息的数字身份证,它的作用与传统的护照或驾驶执照等身份证明相同。
\r\n
\r\n2.防范ASP常见的安全漏洞  

\r\n      通过Web服务器或者程序的漏洞,可以入侵网络服务器,为防止Web服务器收到攻击,笔者列举一下ASP常见的安全漏洞及防范方法。   
\r\n 、IIS的漏洞
\r\n      在IIS环境下运行ASP程序,有以下几种方法可以看到ASP的源代码:
\r\n      (1)在浏览器的地址栏里多加一个小数点。
\r\n      (2)在ASP的URL后多加::$DATA、%81或%2e。
\r\n      (3)替换ASP文件名和后缀名之间的点为%2e%。
\r\n      (4)使用IE的查看源代码功能。

\r\n 、Access数据库可能被下载
\r\n     
如果ASP程序被下载,下载者和容易知道数据库的存放位置并下载它。一旦数据库中含有重要数据,就很危险了。通过以下方法可以有效保护Access数据库:
\r\n      (1)在IIS中设置允许下载的文件的类型来保护数据库文件。
\r\n      (2)可以修改数据库的文件名和文件类型。
\r\n      (3)将数据库放在不容易被发现的多层文件夹中。
\r\n      (4)加密数据库和数据库中的数据。
\r\n      (5)修改Access数据库头文件。

\r\n三、来自FileSystemObject的威胁
\r\n      IIS的ASP文件操作可以通过FileSystemObject实现,但利用FileSystemObject可以篡改和下载FAT分区上的任何文件。管理员应该尽量将Web目录建在NTFS分区上Web目录和非Web目录设置只有管理员才可以完全控制。
\r\n四、ASP应用程序可能面临的攻击
\r\n      如果网站的ASP程序没有把“<”和“>”标签过滤,则可以在ASP程序中写入可执行的ASP代码,通过这些程序可以删除服务器上的一些重要文件。
\r\n
\r\n3.其他安全防护措施
\r\n      (1)修补一致的Windows安全漏洞,并及时安装补丁程序。使用最新版本的Microsoft Internet Information Server,并安装操作系统最新版本的补丁程序。
\r\n      (2)如果服务器的文件为FAT格式,应该修改服务器的文件系统为NTFS格式。
\r\n      (3)把IIS中的Sample、Scripts、IISadmin和MSAdc等Web目录设置为禁止匿名访问并设置IP限制。
\r\n      (4)修改挂李元administrator的账号,账号和密码应尽量设置的复杂,建议使用特殊字符。
\r\n      (5)如果网站数据库为Access,则应该将数据库设置的复杂一些。如#H$879d.345fdf@*$。
\r\n      (6)把FTP、Telnet的Tcp端口改为非标准端口,通常设置在10000~65000的范围内。
\r\n      (7)重要目录用NTFS的特性设置详细的安全权限。
\r\n      (8)采用IIS提供的SSL
安全通信机制来防止数据在网路上被截获。
\r\n      (9)文件上传目录在IIS设置为只读权限,无执行权限。
\r\n      (10)不要将服务器端的错误信息发送到客户端。
\r\n      (11)删除可以删除的所有共享,包括打印机共享和隐藏的共享如ICP$、Admin$等。
\r\n      (12)将ASP目录集中管理,对ASP的程序目录设置详尽的访问权限,一般不要使用“读”的权限。
\r\n      (13)及时备份数据,尤其是数据库数据。
\r\n      (14)只运行需要的服务,禁止所有不应该打开的端口。
\r\n      (15)安装防火墙。
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2921, 'display-return-in-detail-how-iis7-http500-error-message', 'IIS7如何显示、返回详细HTTP500错误信息', '2012-08-14 16:34:11', '2019-03-25 21:29:22', '
\r\n       按住 WIN + R 打开命令行输入 inetmgr 打开 IIS 管理 左边目录选择目标站点,在右边 IIS 块中双击错误页,在错误页中右边的操作中选择编辑->功能设置,在错误响应中,选择详细错误,单击确定完成配置。
\r\n
\r\n       通过命令行启用详细错误:
\r\n

\r\n %windir%system32inetsrvappcmd.exe set config "Default Web Site/yourapp" /section:httpErrors /errorMode:Detailed

\r\n

\r\n 禁用详细错误:

\r\n

\r\n %windir%system32inetsrvappcmd.exe set config "Default Web Site/yourapp" /section:httpErrors /errorMode:Custom

\r\n
\r\n       通过 web.config 配置
\r\n

\r\n       其实,上面在两种配置,最终都会反应到对应的 web.config 中。因此,我们可以直接编辑 web.config。特别是对于买的虚拟主机(Shared Web Hosting),没有权限更改IIS。打开网站目录,找到 web.config 文件(如果没有,就建立一个 txt 文件存为 web.config),找到 system.webServer 配置节,添加配置 <httpErrors errorMode="DetailedLocalOnly" />。

\r\n
\r\n <configuration>
\r\n <system.webServer>
\r\n <httpErrors errorMode="DetailedLocalOnly"/>
\r\n </system.webServer>
\r\n </configuration>
\r\n

\r\n       注意
\r\n       此参数选项可以应用到网站或子目录或虚拟目录。 此参数选项对所有 IIS 应用程序有效,包括 ASP, APS.NET, PHP 等。

\r\n

\r\n       如果是 ASP.NET 程序,可能还需要配置 <customErrors mode=”Off” />
\r\n <system.web>
\r\n <customErrors mode=”Off” />
\r\n </system.web>

\r\n       此外,如果是 ASP 程序,还可以配置 sendErrorsToBrowser 选项:
\r\n       通过 IIS 配置按住 WIN + R 打开命令行输入 inetmgr 打开 IIS 管理 左边目录选择目标站点,在右边 IIS 块中双击 ASP 在 ASP 页中展开 调试属性 节点 找到 启用客户端调试,选择 true 右边 操作中,单击 应用

\r\n
\r\n       通过命令行启用:
\r\n

\r\n %windir%system32inetsrvappcmd set config -section:asp -scriptErrorSentToBrowser:true

\r\n

\r\n 禁用:

\r\n

\r\n %windir%system32inetsrvappcmd set config -section:asp -scriptErrorSentToBrowser:false

\r\n

\r\n 注意上面参数中 config 后面不能指定站点目录。

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2922, 'asp-database-connection-accesssql-server', 'ASP连接Access,Sql Server数据库', '2012-08-14 16:28:37', '2019-03-25 21:29:22', '

\r\n       ASP连接数据库可以使用驱动程序,也可以使用数据源(DateSource,需要在Windows操作系统的控制而板里建立,如果ASP服务器更换需要重新配置才能访问数据库)。不过建议使用驱动程序连接,因为使用驱动程序非常简单,也不会因为ASP移植到其他计算机而重新配置。
\r\n       ODBC连接:

\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n

\r\n 数据库

\r\n
\r\n

\r\n 连接方式

\r\n
\r\n

\r\n Access

\r\n
\r\n

\r\n Driver={microsoft access driver (*.mdb)};dbq=路径及文件名;UID=用户名;PWD=密码;

\r\n
\r\n

\r\n dBase

\r\n
\r\n

\r\n Driver={microsoft dbase driver (*.mdb)};driverid=用户名;dbq=路径及文件名;

\r\n
\r\n

\r\n Oracle

\r\n
\r\n

\r\n Driver={microsoft odbc for oracle};server=oracleserver.world; UID=用户名;PWD=密码;

\r\n
\r\n

\r\n MSSQL server

\r\n
\r\n

\r\n Driver={sql server};servername=服务名;database=数据库名;UID=用户名;PWD=密码;

\r\n
\r\n

\r\n Visual Foxpro

\r\n
\r\n

\r\n Driver={microsoft Visual Foxpro driver};sourcetype=DBC;sourceDB=路径及文件名;exclusive=NO;

\r\n
\r\n

\r\n MySQL

\r\n
\r\n

\r\n Driver={mysql};database=路径及文件名; UID=用户名;PWD=密码;option=16386;

\r\n
\r\n

\r\n  
\r\n       一般情况下,大多数用户都使用Access数据库来进行测试,所以这里给出一个标准的连接Access数据库的方法:
\r\n Set conn = Server.CreateObject(“adodb.connection”)
\r\n Conn.open = “Driver={microsoft access driver (*.mdb)};dbq=” & Server.mapPath(“/db/bbs.mdb”) & “;UID=用户名;PWD=密码;”

\r\n

\r\n 注意:第二个“driver”和后面的括号之间有一个空格,此空格不能去掉。
\r\n
\r\n SQL Server连接方法:
\r\n Set conn = Server.CreateObject("adodb.connection")
\r\n Conn.open  "Driver={sql server}; server=
localhost; database=Enroll ;UID=sa;PWD=105036;"

\r\n
\r\n Recordset对象方法
\r\n Open方法:
\r\n recordset.Open Source,ActiveConnection,CursorType,LockType,Options
\r\n Source

\r\n

\r\n Recordset对象可以通过Source属性来连接Command对象。Source参数可以是一个Command对象名称、一段SQL命令、一个指定的数据表名称或是一个Stored Procedure。假如省略这个参数,系统则采用Recordset对象的Source属性。

\r\n

\r\n ActiveConnection

\r\n

\r\n Recordset对象可以通过ActiveConnection属性来连接Connection对象。这里的ActiveConnection可以是一个Connection对象或是一串包含数据库连接信息(ConnectionString)的字符串参数。

\r\n

\r\n CursorType

\r\n

\r\n Recordset对象Open方法的CursorType参数表示将以什么样的游标类型启动数据,包括adOpenForwardOnly、adOpenKeyset、adOpenDynamic及adOpenStatic,分述如下:

\r\n

\r\n --------------------------------------------------------------

\r\n

\r\n 常数 常数值 说明

\r\n

\r\n -------------------------------------------------------------

\r\n

\r\n adOpenForwardOnly 0 缺省值,启动一个只能向前移动的游标(Forward Only)。

\r\n

\r\n adOpenKeyset 1 启动一个Keyset类型的游标。

\r\n

\r\n adOpenDynamic 2 启动一个Dynamic类型的游标。

\r\n

\r\n adOpenStatic 3 启动一个Static类型的游标。

\r\n

\r\n -------------------------------------------------------------

\r\n

\r\n 以上几个游标类型将直接影响到Recordset对象所有的属性和方法,以下列表说明他们之间的区别。

\r\n

\r\n  

\r\n

\r\n -------------------------------------------------------------

\r\n

\r\n Recordset属性 adOpenForwardOnly adOpenKeyset adOpenDynamic adOpenStatic

\r\n

\r\n -------------------------------------------------------------

\r\n

\r\n AbsolutePage 不支持 不支持 可读写 可读写

\r\n

\r\n AbsolutePosition 不支持 不支持 可读写 可读写

\r\n

\r\n ActiveConnection 可读写 可读写 可读写 可读写

\r\n

\r\n BOF 只读 只读 只读 只读

\r\n

\r\n Bookmark 不支持 不支持 可读写 可读写

\r\n

\r\n CacheSize 可读写 可读写 可读写 可读写

\r\n

\r\n CursorLocation 可读写 可读写 可读写 可读写

\r\n

\r\n CursorType 可读写 可读写 可读写 可读写

\r\n

\r\n EditMode 只读 只读 只读 只读

\r\n

\r\n EOF 只读 只读 只读 只读

\r\n

\r\n Filter 可读写 可读写 可读写 可读写

\r\n

\r\n LockType 可读写 可读写 可读写 可读写

\r\n

\r\n MarshalOptions 可读写 可读写 可读写 可读写

\r\n

\r\n MaxRecords 可读写 可读写 可读写 可读写

\r\n

\r\n PageCount 不支持 不支持 只读 只读

\r\n

\r\n PageSize 可读写 可读写 可读写 可读写

\r\n

\r\n RecordCount 不支持 不支持 只读 只读

\r\n

\r\n Source 可读写 可读写 可读写 可读写

\r\n

\r\n State 只读 只读 只读 只读

\r\n

\r\n Status 只读 只读 只读 只读

\r\n

\r\n AddNew 支持 支持 支持 支持

\r\n

\r\n CancelBatch 支持 支持 支持 支持

\r\n

\r\n CancelUpdate 支持 支持 支持 支持

\r\n

\r\n Clone 不支持 不支持

\r\n

\r\n Close 支持 支持 支持 支持

\r\n

\r\n Delete 支持 支持 支持 支持

\r\n

\r\n GetRows 支持 支持 支持 支持

\r\n

\r\n Move 不支持 支持 支持 支持

\r\n

\r\n MoveFirst 支持 支持 支持 支持

\r\n

\r\n MoveLast 不支持 支持 支持 支持

\r\n

\r\n MoveNext 支持 支持 支持 支持

\r\n

\r\n MovePrevious 不支持 支持 支持 支持

\r\n

\r\n NextRecordset 支持 支持 支持 支持

\r\n

\r\n Open 支持 支持 支持 支持

\r\n

\r\n Requery         支持    支持    支持    支持

\r\n

\r\n Resync        不支持   不支持   支持   支持

\r\n

\r\n Supports        支持     支持    支持    支持

\r\n

\r\n Update         支持     支持    支持    支持

\r\n

\r\n UpdateBatch    支持     支持    支持    支持

\r\n

\r\n --------------------------------------------------------------

\r\n

\r\n 其中NextRecordset方法并不适用于Microsoft Access数据库。

\r\n

\r\n LockType

\r\n

\r\n Recordset对象Open方法的LockType参数表示要采用的Lock类型,如果忽略这个参数,那么系统会以Recordset对象的LockType属性为预设值。LockType参数包含adLockReadOnly、adLockPrssimistic、adLockOptimistic及adLockBatchOptimistic等,分述如下:

\r\n

\r\n  

\r\n

\r\n -------------------------------------------------------------

\r\n

\r\n 常数 常数值 说明

\r\n

\r\n --------------------------------------------------------------

\r\n

\r\n adLockReadOnly 1 缺省值,Recordset对象以只读方式启动,无法运行AddNew、Update及Delete等方法

\r\n

\r\n adLockPrssimistic 2 当数据源正在更新时,系统会暂时锁住其他用户的动作,以保持数据一致性。

\r\n

\r\n adLockOptimistic 3 当数据源正在更新时,系统并不会锁住其他用户的动作,其他用户可以对数据进行增、删、改的操作。

\r\n

\r\n adLockBatchOptimistic 4 当数据源正在更新时,其他用户必须将CursorLocation属性改为adUdeClientBatch才能对数据进行增、

\r\n

\r\n 删、改的操作。 
\r\n
\r\n 记录集对象的方法:

\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n

\r\n rs.movenext

\r\n
\r\n

\r\n 将记录指针从当前的位置向下移一行

\r\n
\r\n

\r\n rs.moveprev

\r\n
\r\n

\r\n 将记录指针从当前的位置向上移一行

\r\n
\r\n

\r\n rs.movefirst

\r\n
\r\n

\r\n 将记录指针移到记录集第一行

\r\n
\r\n

\r\n rs.movelast

\r\n
\r\n

\r\n 将记录指针移到记录集最后一行

\r\n
\r\n

\r\n rs.move[i]

\r\n
\r\n

\r\n 将记录指针下移i行

\r\n
\r\n

\r\n rs.move i,start

\r\n
\r\n

\r\n 将记录指针从start 开始下移i行

\r\n
\r\n

\r\n rs.absoluteposition=n

\r\n
\r\n

\r\n 将记录指针移到记录集第n行

\r\n
\r\n

\r\n rs.absolutepage=n

\r\n
\r\n

\r\n 将记录指针移到第n页的第一行

\r\n
\r\n

\r\n rs.pagesize=n

\r\n
\r\n

\r\n 设置每页为n条记录

\r\n
\r\n

\r\n rs.pagecount

\r\n
\r\n

\r\n 根据 pagesize 的设置返回总页数

\r\n
\r\n

\r\n rs.recordcount

\r\n
\r\n

\r\n 返回记录总数

\r\n
\r\n

\r\n rs.bof

\r\n
\r\n

\r\n 返回记录指针是否超出记录集首端,true表示是,false为否

\r\n
\r\n

\r\n rs.eof

\r\n
\r\n

\r\n 返回记录指针是否超出记录集末端,true表示是,false为否

\r\n
\r\n

\r\n rs.delete

\r\n
\r\n

\r\n 删除当前记录,但记录指针不会向下移动

\r\n
\r\n

\r\n rs.addnew

\r\n
\r\n

\r\n 添加记录到记录集末端

\r\n
\r\n

\r\n rs.update

\r\n
\r\n

\r\n 更新记录集记录

\r\n
\r\n

\r\n rs.fields.count

\r\n
\r\n

\r\n 返回字段数

\r\n
\r\n

\r\n rs.(i).name

\r\n
\r\n

\r\n 返回第i个字段的字段名

\r\n
\r\n

\r\n rs.(i)

\r\n
\r\n

\r\n 返回第i个字段的值

\r\n
\r\n

\r\n rs(“字段名”)

\r\n
\r\n

\r\n 返回该字段的值

\r\n
\r\n

\r\n rs.open

\r\n
\r\n

\r\n 打开recordset 对象,执行查询

\r\n
\r\n

\r\n rs.close

\r\n
\r\n

\r\n 关闭 recordset 对象

\r\n
\r\n

\r\n  

\r\n
\r\n

\r\n RS.OPEN   SQL,CONN,A,B
\r\n
\r\n A:
\r\n
\r\n ADOPENFORWARDONLY(=0)  
\r\n 只读,且当前数据记录只能向下移动
\r\n
\r\n ADOPENKEYSET(=1)      
\r\n 只读,当前数据记录可自由移动
\r\n
\r\n ADOPENDYNAMIC(=2)      
\r\n 可读写,当前数据记录可自由移动
\r\n
\r\n ADOPENSTATIC(=3)      
\r\n 可读写,当前数据记录可自由移动,可看到新增记录
\r\n
\r\n B:
\r\n
\r\n ADLOCKREADONLY(=1)     
\r\n 缺省锁定类型,记录集是只读的,不能修改记录
\r\n
\r\n ADLOCKPESSIMISTIC(=2)  
\r\n 悲观锁定,当修改记录时,数据提供者将尝试锁定记录以确保成功地编辑记录。只要编辑一开始,则立即锁住记录。
\r\n
\r\n ADLOCKOPTIMISTIC(=3)   
\r\n 乐观锁定 ,直到用Update方法提交更新记录时才锁定记录。
\r\n
\r\n ADLOCKBATCHOPTIMISTIC(=4)  
\r\n 批量乐观锁定,允许修改多个记录,只有调用UpdateBatch方法后才锁定记录。
\r\n
\r\n 当不需要改动任何记录时,应该使用只读的记录集,这样提供者不用做任何检测。
\r\n 对于一般的使用,乐观的锁定可能是最好的选择,因为记录只被锁定一小段时间,
\r\n 数据在这段时间被更新。这减少了资源的使用。
\r\n
\r\n 应用实例:

\r\n ASP连接Access数据库
\r\n <%@LANGUAGE="VBSCRIPT" CODEPAGE="65001"%>
\r\n <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
\r\n <html xmlns="http://www.w3.org/1999/xhtml">
\r\n <head>
\r\n <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
\r\n <title>Access数据库连接测试</title>
\r\n </head>

\r\n <body>
\r\n <center>Access数据库连接成功!</center>
\r\n
\r\n <%
\r\n Dim conn
\r\n Set conn = Server.CreateObject("adodb.connection")
\r\n Conn.open = "Driver={microsoft access driver (*.mdb)};dbq=" & Server.mapPath("
xhnew.mdb") & ";UID=;PWD=;"
\r\n %>
\r\n
\r\n </body>
\r\n </html>

\r\n
\r\n
\r\n ASP连接Sql Server数据库
\r\n <%@LANGUAGE="VBSCRIPT" CODEPAGE="65001"%>
\r\n <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
\r\n <html xmlns="http://www.w3.org/1999/xhtml">
\r\n <head>
\r\n <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
\r\n <title>Sql Server数据库连接测试</title>
\r\n </head>

\r\n <body>
\r\n <center>Sql Server数据库连接成功!</center>
\r\n
\r\n <%
\r\n Dim conn
\r\n Set conn = Server.CreateObject("adodb.connection")
\r\n Conn.open  "Driver={sql server}; server=
localhost; database=Enroll ;UID=sa;PWD=105036;"
\r\n %>
\r\n
\r\n </body>
\r\n </html>

\r\n  

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2923, 'android-project-directory-details', 'Android项目目录详解', '2012-08-14 07:06:32', '2019-03-25 21:29:22', '      打开Eclipse,创建名叫Hello的Android项目,展开列表如图:
\r\n
\r\n      各包的用途:
\r\n      src: 专门存放我们编写的java源代码的包。\r\n

\r\n       gen: 该目录不用我们开发人员维护,但又非常重要的目录。该目录用来存放由Android开发工具所生成的目录。该目录下的所有文件都不是我们创建的,而是由ADT自动生成的。该目录下的R.java文件非常重要。

\r\n

\r\n       android 2.2: 存放Android自身的jar包。

\r\n

\r\n       assets:该目录用来存放应用中用到的类似于视频文件、Mp3一些媒体文件。

\r\n

\r\n res:res是resource的缩写,我们称该目录为资源目录。该目录可以存放一些图标、界面文件、应用到的文字信息。

\r\n

\r\n       res下有三个dawable文件夹:

\r\n

\r\n drawable-hdpi:用来存放高分辨率的图标;

\r\n

\r\n drawable-mdpi:用来存放中等分辨路的图标;

\r\n

\r\n drawable-ldpi:用来存放低分辨率的图标。

\r\n

\r\n 程序运行时可以根据手机分辨率的高低选取相应的目录下的图标。

\r\n

\r\n       res下还有一个layout文件夹,里面是ADT默认自动创建的main.xml文件,在mian.xml中存放的是布局文件。下面试mian.xml中的部分代码:

\r\n

\r\n \"\"

\r\n

\r\n       res下的values中的strings.xml用来定义字符串和数值,在Activity中使用getResources().getString(resourceId)或getResources().getText(resourceId)取得资源。

\r\n

\r\n 下面是strings.xml中的部分代码:

\r\n

\r\n \"\"

\r\n

\r\n       AndroidManifest.xml:该文件是功能清单文件,该文件列出了应用中所使用的所有组件,如“activity”。

\r\n

\r\n       proguard.cfg:混淆脚本文件。

\r\n

\r\n       project.properties:该文件存放了项目的一些环境配置,根据需要可以手工改动。可以将7改为3,4,7,8,10,11,12,13,14中的任意数值。

\r\n

\r\n \"\"

\r\n

\r\n  

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2924, 'android-sdk-directory-and-install-apk-package-directory-details', 'Android SDK目录及APK安装包目录详解', '2012-08-14 06:42:30', '2019-03-25 21:29:22', '

\r\n Android SDK目录详解:
\r\n
\r\n       1. add-ons/ 这里面保存着你开发附加应用或者在其它设备上开发Android应用时需要的附加类库,比如google Maps,当然你如果安装OPhone SDK,这里也会有一些类库在里面。
\r\n       2. docs/ 这里面包括开发指南、Android SDK API参考文档等,所有的API都可以在这里查到。
\r\n       3. extras/ Android SDK的附加组件。
\r\n       4. platforms/ 是每个平台的SDK真正的文件,里面会根据API Level划分的SDK版本,以Android 2.2来说,进入后有一个android-8的文件夹,android-8进入后是Android 2.2 SDK的主要文件,其中ant为ant编译脚本,data保存着一些系统资源,images是模拟器映像文件,skins则是Android模拟器的皮肤,templates是工程创建的默认模板,android.jar则是该版本的主要framework文件。
\r\n       5. platform-tools/ 保存着一些通用工具,比如adb、和aapt、aidl、dx等文件。
\r\n       6. samples/ 是Android SDK自带的默认示例工程,里面的apidemos适合初学者运行学习,对于SQLite数据库操作可以查看NotePad这个例子,对于游戏开发Snake、LunarLander都是不错的例子,对于Android主题开发Home则是android m5时代的主题设计原理。
\r\n       7.system-images/ 更新版本产生的系统资源、映像等等。
\r\n       8.temp/ 更新SDK时的临时文件存放文件夹。

\r\n       9. tools/ 作为SDK根目录下的tools文件夹,这里包含了重要的工具,比如ddms用于启动Android调试工具,比如logcat、屏幕截图和文件管理器,而draw9patch则是绘制android平台的可缩放png图片的工具,sqlite3可以在PC上操作SQLite数据库,而monkeyrunner则是一个不错的压力测试应用,模拟用户随机按键,mksdcard则是模拟器SD映像的创建工具,emulator是android模拟器主程序,不过从android 1.5开始,需要输入合适的参数才能启动模拟器,traceview作为android平台上重要的调试工具。
\r\n       10.AVD Manager.exe 创建安卓模拟器的工具。
\r\n       11.SDK Manager.exe 更新Android SDK的工具。
\r\n       12.SDK Readme.txt 安卓版本的说明文件。

\r\n
\r\n 安装包(apk)目录结构详解:

\r\n

\r\n       1. META-INF  Jar文件中常可以看到;

\r\n

\r\n       2. res  存放资源文件的目录);

\r\n

\r\n       3. AndroidManifest.xml 程序全局配置文件 ;

\r\n

\r\n       4. classes.dex Dalvik字节码;

\r\n

\r\n       5. resources.arsc 编译后的二进制资源文件。

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2925, 'failed-to-fetch-url-android-sdk-installation', '安装Android SDK出现Failed to fetch URL ...', '2012-08-14 05:31:55', '2019-03-25 21:29:22', '        最近有一个项目要用安卓开发,记得以前装过Android SDK,今天照例。先下载Eclipse,又装好了ADT,可是在装Android SDK时却出现了
\r\nFetching http://dl-ssl.google.com/android/repository/addons_list-1.xml
\r\nFailed to fetch URL http://dl-ssl.google.com/android/repository/addons_list-1.xml, reason: Connection to http://dl-ssl.google.com refused
\r\nFetched Add-ons List successfully
\r\nFetching URL: http://dl-ssl.google.com/android/repository/repository-6.xml
\r\nFailed to fetch URL http://dl-ssl.google.com/android/repository/repository-6.xml, reason: Connection to http://dl-ssl.google.com refused
\r\nDone loading packages.

\r\n        网上查资料,终于在谷歌官网找到了答案
\r\nhttp://code.google.com/p/android/issues/detail?can=2&start=0&num=100&q=&colspec=ID%20Type%20Status%20Owner%20Summary%20Stars&groupby=&sort=&id=21359
\r\n      具体操作:
\r\n1.用记事本或Gvim打开C:WINDOWSsystem32driversetc中的hosts文件
\r\n2.在最后一行添加74.125.237.1 dl-ssl.google.com
\r\n3.成功解决问题。
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2927, 'ubuntu-linux-flash-garbled-solution', 'ubuntu/linux flash中文乱码的解决方案', '2012-06-22 03:05:55', '2019-03-25 21:29:22', '打开配置文件:
\r\ncd /etc/fonts/conf.d/
\r\nsudo gedit 49-sansserif.conf

\r\n
\r\n修改edit节点,将<string>sans-serif</string>
\r\n改为 <string>sans</string>
\r\n
\r\n<match target="pattern">
\r\n<test qual="all" name="family" compare="not_eq">
\r\n<string>sans-serif</string>
\r\n</test>
\r\n<test qual="all" name="family" compare="not_eq">
\r\n<string>serif</string>
\r\n</test>
\r\n<test qual="all" name="family" compare="not_eq">
\r\n<string>monospace</string>
\r\n</test>
\r\n<edit name="family" mode="append_last">

\r\n<string>sans-serif</string> 这里改为<--- <string>sans</string>
\r\n</edit>
\r\n</match>

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2930, 'detailed-explanation-of-kmp-algorithm-of-string-pattern-matching-2', 'KMP算法字符串模式匹配详解', '2012-06-03 00:21:07', '2019-03-25 21:29:22', '
\r\n       KMP字符串模式匹配通俗点说就是一种在一个字符串中定位另一个串的高效算法。简单匹配算法的时间复杂度为O(m*n),而KMP匹配算法,可以证明它的时间复杂度为O(m+n)。
\r\n
\r\n 一.简单匹配算法
\r\n
\r\n       先来看一个简单匹配算法的函数:
\r\n
\r\n int Index_BF ( char S [ ], char T [ ], int pos )
\r\n
\r\n {
\r\n
\r\n /* 若串 S 中从第pos(S 的下标0≤pos<StrLength(S))个字符
\r\n
\r\n 起存在和串 T 相同的子串,则称匹配成功,返回第一个
\r\n
\r\n 这样的子串在串 S 中的下标,否则返回 -1    */
\r\n
\r\n int i = pos, j = 0;
\r\n
\r\n while ( S[i+j] != ' '&& T[j] != ' ')
\r\n
\r\n if ( S[i+j] == T[j] )
\r\n
\r\n j ++; // 继续比较后一字符
\r\n
\r\n else
\r\n
\r\n {
\r\n
\r\n i ++; j = 0; // 重新开始新的一轮匹配
\r\n
\r\n }
\r\n
\r\n if ( T[j] == ' ')
\r\n
\r\n return i; // 匹配成功   返回下标
\r\n
\r\n else
\r\n
\r\n return -1; // 串S中  (第pos个字符起)不存在和串T相同的子串
\r\n
\r\n } // Index_BF
\r\n        此算法的思想是直截了当的:将主串S中某个位置i起始的子串和模式串T相比较。即从j=0 起比较 S[i+j] 与 T[j],若相等,则在主串 S 中存在以 i 为起始位置匹配成功的可能性,继续往后比较( j逐步增1 ),直至与T串中最后一个字符相等为止,否则改从S串的下一个字符起重新开始进行下一轮的"匹配",即将串T向后滑动一位,即 i 增1,而 j 退回至0,重新开始新一轮的匹配。
\r\n
\r\n       例如:在串S=”abcabcabdabba”中查找T=” abcabd”(我们可以假设从下标0开始):先是比较S[0]和T[0]是否相等,然后比较S[1] 和T[1]是否相等…我们发现一直比较到S[5] 和T[5]才不等。如图:
\r\n
\r\n \"\"
\r\n       当这样一个失配发生时,T下标必须回溯到开始,S下标回溯的长度与T相同,然后S下标增1,然后再次比较。如图:
\r\n
\r\n 这次立刻发生了失配,T下标又回溯到开始,S下标增1,然后再次比较。如图:
\r\n
\r\n \"\"
\r\n       这次立刻发生了失配,T下标又回溯到开始,S下标增1,然后再次比较。如图:
\r\n
\r\n \"\"
\r\n       又一次发生了失配,所以T下标又回溯到开始,S下标增1,然后再次比较。这次T中的所有字符都和S中相应的字符匹配了。函数返回T在S中的起始下标3。如图:
\r\n \"\"
\r\n
\r\n
\r\n 二. KMP匹配算法
\r\n
\r\n       还是相同的例子,在S=”abcabcabdabba”中查找T=”abcabd”,如果使用KMP匹配算法,当第一次搜索到S[5] 和T[5]不等后,S下标不是回溯到1,T下标也不是回溯到开始,而是根据T中T[5]==’d’的模式函数值(next[5]=2,为什么?后面讲),直接比较S[5] 和T[2]是否相等,因为相等,S和T的下标同时增加;因为又相等,S和T的下标又同时增加,最终在S中找到了T。如图:
\r\n
\r\n \"\"
\r\n       KMP匹配算法和简单匹配算法效率比较,一个极端的例子是:
\r\n
\r\n       在S=“AAAAAA…AAB“(100个A)中查找T=”AAAAAAAAAB”, 简单匹配算法每次都是比较到T的结尾,发现字符不同,然后T的下标回溯到开始,S的下标也要回溯相同长度后增1,继续比较。如果使用KMP匹配算法,就不必回溯.
\r\n
\r\n       对于一般文稿中串的匹配,简单匹配算法的时间复杂度可降为O (m+n),因此在多数的实际应用场合下被应用。
\r\n
\r\n       KMP算法的核心思想是利用已经得到的部分匹配信息来进行后面的匹配过程。看前面的例子。为什么T[5]==’d’的模式函数值等于2(next[5]=2),其实这个2表示T[5]==’d’的前面有2个字符和开始的两个字符相同,且T[5]==’d’不等于开始的两个字符之后的第三个字符(T[2]=’c’).如图:
\r\n
\r\n \"\"
\r\n
\r\n       也就是说,如果开始的两个字符之后的第三个字符也为’d’,那么,尽管T[5]==’d’的前面有2个字符和开始的两个字符相同,T[5]==’d’的模式函数值也不为2,而是为0。
\r\n
\r\n       前面我说:在S=”abcabcabdabba”中查找T=”abcabd”,如果使用KMP匹配算法,当第一次搜索到S[5] 和T[5]不等后,S下标不是回溯到1,T下标也不是回溯到开始,而是根据T中T[5]==’d’的模式函数值,直接比较S[5] 和T[2]是否相等,为什么可以这样?
\r\n
\r\n       刚才我又说:“(next[5]=2),其实这个2表示T[5]==’d’的前面有2个字符和开始的两个字符相同”。请看图 :因为,S[4] ==T[4],S[3] ==T[3],根据next[5]=2,有T[3]==T[0],T[4] ==T[1],所以S[3]==T[0],S[4] ==T[1](两对相当于间接比较过了),因此,接下来比较S[5] 和T[2]是否相等。。。
\r\n
\r\n \"\"
\r\n
\r\n       有人可能会问:S[3]和T[0],S[4] 和T[1]是根据next[5]=2间接比较相等,那S[1]和T[0],S[2] 和T[0]之间又是怎么跳过,可以不比较呢?因为S[0]=T[0],S[1]=T[1],S[2]=T[2],而T[0] != T[1], T[1] != T[2],==> S[0] != S[1],S[1] != S[2],所以S[1] != T[0],S[2] != T[0]. 还是从理论上间接比较了。
\r\n
\r\n 有人疑问又来了,你分析的是不是特殊轻况啊。
\r\n
\r\n       假设S不变,在S中搜索T=“abaabd”呢?答:这种情况,当比较到S[2]和T[2]时,发现不等,就去看next[2]的值,next[2]=-1,意思是S[2]已经和T[0] 间接比较过了,不相等,接下来去比较S[3]和T[0]吧。
\r\n       假设S不变,在S中搜索T=“abbabd”呢?答:这种情况当比较到S[2]和T[2]时,发现不等,就去看next[2]的值,next[2]=0,意思是S[2]已经和T[2]比较过了,不相等,接下来去比较S[2]和T[0]吧。
\r\n
\r\n       假设S=”abaabcabdabba”在S中搜索T=“abaabd”呢?答:这种情况当比较到S[5]和T[5]时,发现不等,就去看next[5]的值,next[5]=2,意思是前面的比较过了,其中,S[5]的前面有两个字符和T的开始两个相等,接下来去比较S[5]和T[2]吧。
\r\n
\r\n       总之,有了串的next值,一切搞定。那么,怎么求串的模式函数值next[n]呢?(本文中next值、模式函数值、模式值是一个意思。)
\r\n
\r\n 三. 怎么求串的模式值next[n]
\r\n
\r\n 定义:
\r\n
\r\n (1)next[0]= -1 
\r\n       意义:任何串的第一个字符的模式值规定为-1。
\r\n
\r\n (2)next[j]= -1  
\r\n       意义:模式串T中下标为j的字符,如果与首字符
相同,且j的前面的j—k个字符与开头的j—k个字符不等(或者相等但T[k]==T[j])(1≤k<j)。
\r\n
\r\n 如:T=”abCabCad” 则 next[6]=-1,因T[3]=T[6]
\r\n
\r\n (3)next[j]=k   
\r\n       意义:模式串T中下标为j的字符,如果j的前面k个
字符与开头的k个字符相等,且T[j] != T[k] (1≤k<j)。
\r\n
\r\n 即T[0]T[1]T[2]。。。T[k-1]==T[j-k]T[j-k+1]T[j-k+2]…T[j-1] 且T[j] != T[k].(1≤k<j);
\r\n
\r\n (4) next[j]=0  
\r\n       意义:除(1)(2)(3)的其他情况。
\r\n
\r\n  
\r\n
\r\n 举例:
\r\n
\r\n 01)求T=“abcac”的模式函数的值。
\r\n
\r\n      next[0]= -1 根据(1)
\r\n
\r\n      next[1]=0   根据 (4)   因(3)有1<=k<j;不能说,j=1,T[j-1]==T[0]
\r\n
\r\n      next[2]=0   根据 (4)   因(3)有1<=k<j;(T[0]=a)!=(T[1]=b)
\r\n
\r\n      next[3]= -1 根据 (2)
\r\n
\r\n      next[4]=1   根据 (3) T[0]=T[3] 且 T[1]!=T[4]
\r\n
\r\n     即   
\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n 下标
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 1
\r\n
\r\n
\r\n 2
\r\n
\r\n
\r\n 3
\r\n
\r\n
\r\n 4
\r\n
\r\n
\r\n T
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n b
\r\n
\r\n
\r\n c
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n c
\r\n
\r\n
\r\n next
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 1
\r\n
\r\n
\r\n 若T=“abcab”将是这样:
\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n 下标
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 1
\r\n
\r\n
\r\n 2
\r\n
\r\n
\r\n 3
\r\n
\r\n
\r\n 4
\r\n
\r\n
\r\n T
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n b
\r\n
\r\n
\r\n c
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n b
\r\n
\r\n
\r\n next
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 为什么T[0]==T[3],还会有next[4]=0呢, 因为T[1]==T[4], 根据 (3)” 且T[j] != T[k]”被划入(4)。
\r\n
\r\n 02)来个复杂点的,求T=”ababcaabc” 的模式函数的值。
\r\n
\r\n next[0]= -1    根据(1)
\r\n
\r\n next[1]=0    根据(4)
\r\n
\r\n next[2]=-1   根据 (2)
\r\n
\r\n next[3]=0   根据 (3) 虽T[0]=T[2] 但T[1]=T[3] 被划入(4)
\r\n
\r\n next[4]=2   根据 (3) T[0]T[1]=T[2]T[3] 且T[2] !=T[4]
\r\n
\r\n next[5]=-1 根据 (2) 
\r\n
\r\n next[6]=1   根据 (3) T[0]=T[5] 且T[1]!=T[6]
\r\n
\r\n next[7]=0   根据 (3) 虽T[0]=T[6] 但T[1]=T[7] 被划入(4)
\r\n
\r\n next[8]=2   根据 (3) T[0]T[1]=T[6]T[7] 且T[2] !=T[8]
\r\n
\r\n  即
\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n 下标
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 1
\r\n
\r\n
\r\n 2
\r\n
\r\n
\r\n 3
\r\n
\r\n
\r\n 4
\r\n
\r\n
\r\n 5
\r\n
\r\n
\r\n 6
\r\n
\r\n
\r\n 7
\r\n
\r\n
\r\n 8
\r\n
\r\n
\r\n T
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n b
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n b
\r\n
\r\n
\r\n c
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n b
\r\n
\r\n
\r\n c
\r\n
\r\n
\r\n next
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 2
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 2
\r\n
\r\n
\r\n 只要理解了next[3]=0,而不是=1,next[6]=1,而不是= -1,next[8]=2,而不是= 0,其他的好象都容易理解。
\r\n
\r\n 03)   来个特殊的,求 T=”abCabCad” 的模式函数的值。
\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n 下标
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 1
\r\n
\r\n
\r\n 2
\r\n
\r\n
\r\n 3
\r\n
\r\n
\r\n 4
\r\n
\r\n
\r\n 5
\r\n
\r\n
\r\n 6
\r\n
\r\n
\r\n 7
\r\n
\r\n
\r\n T
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n b
\r\n
\r\n
\r\n C
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n b
\r\n
\r\n
\r\n C
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n d
\r\n
\r\n
\r\n next
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 4
\r\n
\r\n
\r\n next[0]= -1
\r\n next[1]= 0
\r\n next[2]= 0
\r\n next[3]= -1
\r\n next[4]= 0     
\r\n
\r\n next[5]= 0 根据 (3) 虽T[0]T[1]=T[3]T[4],但T[2]==T[5]
\r\n
\r\n next[6]= -1 根据 (2) 虽前面有abC=abC,但T[3]==T[6]
\r\n
\r\n next[7]=4   根据 (3) 前面有abCa=abCa,且 T[4]!=T[7]
\r\n
\r\n 若T[4]==T[7],即T=” adCadCad”,那么将是这样:next[7]=0, 而不是= 4,因为T[4]==T[7].
\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n 下标
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 1
\r\n
\r\n
\r\n 2
\r\n
\r\n
\r\n 3
\r\n
\r\n
\r\n 4
\r\n
\r\n
\r\n 5
\r\n
\r\n
\r\n 6
\r\n
\r\n
\r\n 7
\r\n
\r\n
\r\n T
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n d
\r\n
\r\n
\r\n C
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n d
\r\n
\r\n
\r\n C
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n d
\r\n
\r\n
\r\n next
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n  
\r\n
\r\n 如果你觉得有点懂了,那么
\r\n
\r\n 练习:求T=”AAAAAAAAAAB” 的模式函数值,并用后面的求模式函数值函数验证。
\r\n
\r\n 意义:
\r\n
\r\n       next 函数值究竟是什么含义,前面说过一些,这里总结。
\r\n
\r\n 设在字符串S中查找模式串T,若S[m]!=T[n],那么,取T[n]的模式函数值next[n]
\r\n
\r\n 1. next[n]= -1 表示S[m]和T[0]间接比较过了,不相等,下一次比较 S[m+1] 和T[0]
\r\n
\r\n 2.next[n]=0 表示比较过程中产生了不相等,下一次比较 S[m] 和T[0]。
\r\n
\r\n 3.next[n]= k >0 但k<n, 表示,S[m]的前k个字符与T中的开始k个字符已经间接比较相等了,下一次比较S[m]和T[k]相等吗?
\r\n
\r\n 4.其他值,不可能。
\r\n
\r\n 四. 求串T的模式值next[n]的函数
\r\n
\r\n       说了这么多,是不是觉得求串T的模式值next[n]很复杂呢?要叫我写个函数出来,目前来说,我宁愿去登天。好在有现成的函数,当初发明KMP算法,写出这个函数的先辈,令我佩服得六体投地。我等后生小子,理解起来,都要反复琢磨。下面是这个函数:
\r\n
\r\n void get_nextval(const char *T, int next[])
\r\n
\r\n {
\r\n
\r\n        // 求模式串T的next函数值并存入数组 next。
\r\n
\r\n        int j = 0, k = -1;
\r\n
\r\n        next[0] = -1;
\r\n
\r\n        while ( T[j/*+1*/] != '/0' )
\r\n
\r\n        {
\r\n
\r\n               if (k == -1 || T[j] == T[k])
\r\n
\r\n               {
\r\n
\r\n                      ++j; ++k;
\r\n
\r\n                      if (T[j]!=T[k])
\r\n
\r\n                             next[j] = k;
\r\n
\r\n                      else
\r\n
\r\n                             next[j] = next[k];
\r\n
\r\n               }// if
\r\n
\r\n               else
\r\n
\r\n                      k = next[k];
\r\n
\r\n        }// while
\r\n
\r\n     ////这里是我加的显示部分
\r\n
\r\n    // for(int i=0;i<j;i++)
\r\n
\r\n        //{
\r\n
\r\n        //     cout<<next[i];
\r\n
\r\n        //}
\r\n
\r\n        //cout<<endl;
\r\n
\r\n }// get_nextval 
\r\n
\r\n 另一种写法,也差不多。
\r\n
\r\n void getNext(const char* pattern,int next[])
\r\n
\r\n {
\r\n
\r\n        next[0]=   -1;
\r\n
\r\n        int k=-1,j=0;
\r\n
\r\n        while(pattern[j] != '/0')
\r\n
\r\n        {
\r\n
\r\n               if(k!= -1 && pattern[k]!= pattern[j] )
\r\n
\r\n                      k=next[k];
\r\n
\r\n               ++j;++k;
\r\n
\r\n               if(pattern[k]== pattern[j])
\r\n
\r\n                      next[j]=next[k];
\r\n
\r\n               else
\r\n
\r\n                      next[j]=k;
\r\n
\r\n        }
\r\n
\r\n        ////这里是我加的显示部分
\r\n
\r\n    // for(int i=0;i<j;i++)
\r\n
\r\n        //{
\r\n
\r\n        //     cout<<next[i];
\r\n
\r\n        //}
\r\n
\r\n        //cout<<endl;
\r\n
\r\n }
\r\n
\r\n 下面是KMP模式匹配程序,各位可以用他验证。记得加入上面的函数
\r\n
\r\n #include <iostream.h>
\r\n
\r\n #include <string.h>
\r\n
\r\n int KMP(const char *Text,const char* Pattern) //const 表示函数内部不会改变这个参数的值。
\r\n
\r\n {
\r\n
\r\n        if( !Text||!Pattern|| Pattern[0]=='/0' || Text[0]=='/0' )//
\r\n
\r\n               return -1;//空指针或空串,返回-1。
\r\n
\r\n        int len=0;
\r\n
\r\n        const char * c=Pattern;
\r\n
\r\n        while(*c++!='/0')//移动指针比移动下标快。
\r\n
\r\n        {    
\r\n
\r\n               ++len;//字符串长度。
\r\n
\r\n        }
\r\n
\r\n        int *next=new int[len+1];
\r\n
\r\n        get_nextval(Pattern,next);//求Pattern的next函数值
\r\n
\r\n    
\r\n
\r\n        int index=0,i=0,j=0;
\r\n
\r\n        while(Text[i]!='/0' && Pattern[j]!='/0' )
\r\n
\r\n        {
\r\n
\r\n               if(Text[i]== Pattern[j])
\r\n
\r\n               {
\r\n
\r\n                      ++i;// 继续比较后继字符
\r\n
\r\n                      ++j;
\r\n
\r\n               }
\r\n
\r\n               else
\r\n
\r\n               {
\r\n
\r\n                      index += j-next[j];
\r\n
\r\n                      if(next[j]!=-1)
\r\n
\r\n                             j=next[j];// 模式串向右移动
\r\n
\r\n                      else
\r\n
\r\n                      {
\r\n
\r\n                             j=0;
\r\n
\r\n                             ++i;
\r\n
\r\n                      }
\r\n
\r\n               }
\r\n
\r\n        }//while
\r\n
\r\n    
\r\n
\r\n        delete []next;
\r\n
\r\n        if(Pattern[j]=='/0')
\r\n
\r\n               return index;// 匹配成功
\r\n
\r\n        else
\r\n
\r\n               return -1;      
\r\n
\r\n }
\r\n
\r\n int main()//abCabCad
\r\n
\r\n {
\r\n
\r\n        char* text="bababCabCadcaabcaababcbaaaabaaacababcaabc";
\r\n
\r\n     char*pattern="adCadCad";
\r\n
\r\n        //getNext(pattern,n);
\r\n
\r\n     //get_nextval(pattern,n);
\r\n
\r\n       cout<<KMP(text,pattern)<<endl;
\r\n
\r\n        return 0;
\r\n
\r\n }
\r\n
\r\n 五.其他表示模式值的方法
\r\n
\r\n       上面那种串的模式值表示方法是最优秀的表示方法,从串的模式值我们可以得到很多信息,以下称为第一种表示方法。第二种表示方法,虽然也定义next[0]= -1,但后面绝不会出现-1,除了next[0],其他模式值next[j]=k(0≤k<j)的意义可以简单看成是:下标为j的字符的前面最多k个字符与开始的k个字符相同,这里并不要求T[j] != T[k]。其实next[0]也可以定义为0(后面给出的求串的模式值的函数和串的模式匹配的函数,是next[0]=0的),这样,next[j]=k(0≤k<j)的意义都可以简单看成是:下标为j的字符的前面最多k个字符与开始的k个字符相同。第三种表示方法是第一种表示方法的变形,即按第一种方法得到的模式值,每个值分别加1,就得到第三种表示方法。第三种表示方法,我是从论坛上看到的,没看到详细解释,我估计是为那些这样的编程语言准备的:数组的下标从1开始而不是0。
\r\n
\r\n       下面给出几种方法的例子:
\r\n
\r\n       表一。
\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n 下标
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 1
\r\n
\r\n
\r\n 2
\r\n
\r\n
\r\n 3
\r\n
\r\n
\r\n 4
\r\n
\r\n
\r\n 5
\r\n
\r\n
\r\n 6
\r\n
\r\n
\r\n 7
\r\n
\r\n
\r\n 8
\r\n
\r\n
\r\n T
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n b
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n b
\r\n
\r\n
\r\n c
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n b
\r\n
\r\n
\r\n c
\r\n
\r\n
\r\n (1) next
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 2
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 2
\r\n
\r\n
\r\n (2) next
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 1
\r\n
\r\n
\r\n 2
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 1
\r\n
\r\n
\r\n 1
\r\n
\r\n
\r\n 2
\r\n
\r\n
\r\n (3) next
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 1
\r\n
\r\n
\r\n 3
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 2
\r\n
\r\n
\r\n 1
\r\n
\r\n
\r\n 3
\r\n
\r\n
\r\n       第三种表示方法,在我看来,意义不是那么明了,不再讨论。
\r\n
\r\n       表二。
\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n 下标
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 1
\r\n
\r\n
\r\n 2
\r\n
\r\n
\r\n 3
\r\n
\r\n
\r\n 4
\r\n
\r\n
\r\n T
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n b
\r\n
\r\n
\r\n c
\r\n
\r\n
\r\n A
\r\n
\r\n
\r\n c
\r\n
\r\n
\r\n (1)next
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 1
\r\n
\r\n
\r\n (2)next
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 1
\r\n
\r\n
\r\n       表三。
\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n 下标
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 1
\r\n
\r\n
\r\n 2
\r\n
\r\n
\r\n 3
\r\n
\r\n
\r\n 4
\r\n
\r\n
\r\n 5
\r\n
\r\n
\r\n 6
\r\n
\r\n
\r\n 7
\r\n
\r\n
\r\n T
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n d
\r\n
\r\n
\r\n C
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n d
\r\n
\r\n
\r\n C
\r\n
\r\n
\r\n a
\r\n
\r\n
\r\n d
\r\n
\r\n
\r\n (1)next
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n (2)next
\r\n
\r\n
\r\n -1
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 0
\r\n
\r\n
\r\n 1
\r\n
\r\n
\r\n 2
\r\n
\r\n
\r\n 3
\r\n
\r\n
\r\n 4
\r\n
\r\n
\r\n  
\r\n
\r\n       对比串的模式值第一种表示方法和第二种表示方法,看表一:
\r\n
\r\n 第一种表示方法next[2]= -1,表示T[2]=T[0],且T[2-1] !=T[0]
\r\n
\r\n 第二种表示方法next[2]= 0,表示T[2-1] !=T[0],但并不管T[0] 和T[2]相不相等。
\r\n
\r\n 第一种表示方法next[3]= 0,表示虽然T[2]=T[0],但T[1] ==T[3]
\r\n
\r\n 第二种表示方法next[3]= 1,表示T[2] =T[0],他并不管T[1] 和T[3]相不相等。
\r\n
\r\n 第一种表示方法next[5]= -1,表示T[5]=T[0],且T[4] !=T[0],T[3]T[4] !=T[0]T[1],T[2]T[3]T[4] !=T[0]T[1]T[2]
\r\n
\r\n 第二种表示方法next[5]= 0,表示T[4] !=T[0],T[3]T[4] !=T[0]T[1] ,T[2]T[3]T[4] !=T[0]T[1]T[2],但并不管T[0] 和T[5]相不相等。换句话说:就算T[5]==’x’,或 T[5]==’y’,T[5]==’9’,也有next[5]= 0 。
\r\n
\r\n       从这里我们可以看到:串的模式值第一种表示方法能表示更多的信息,第二种表示方法更单纯,不容易搞错。当然,用第一种表示方法写出的模式匹配函数效率更高。比如说,在串S=“adCadCBdadCadCad 9876543”中匹配串T=“adCadCad”, 用第一种表示方法写出的模式匹配函数,当比较到S[6] != T[6] 时,取next[6]= -1(表三),它可以表示这样许多信息: S[3]S[4]S[5]==T[3]T[4]T[5]==T[0]T[1]T[2],而S[6] != T[6],T[6]==T[3]==T[0],所以S[6] != T[0],接下来比较S[7]和T[0]吧。如果用第二种表示方法写出的模式匹配函数,当比较到S[6] != T[6] 时,取next[6]= 3(表三),它只能表示:S[3]S[4]S[5]== T[3]T[4]T[5]==T[0]T[1]T[2],但不能确定T[6]与T[3]相不相等,所以,接下来比较S[6]和T[3];又不相等,取next[3]= 0,它表示S[3]S[4]S[5]== T[0]T[1]T[2],但不会确定T[3]与T[0]相不相等,即S[6]和T[0] 相不相等,所以接下来比较S[6]和T[0],确定它们不相等,然后才会比较S[7]和T[0]。是不是比用第一种表示方法写出的模式匹配函数多绕了几个弯。
\r\n
\r\n       为什么,在讲明第一种表示方法后,还要讲没有第一种表示方法好的第二种表示方法?原因是:最开始,我看严蔚敏的一个讲座,她给出的模式值表示方法是我这里的第二种表示方法,如图:
\r\n
\r\n 她说:“next 函数值的含义是:当出现S[i] !=T[j]时,下一次的比较应该在S[i]和T[next[j]] 之间进行。”虽简洁,但不明了,反复几遍也没明白为什么。而她给出的算法求出的模式值是我这里说的第一种表示方法next值,就是前面的get_nextval()函数。匹配算法也是有瑕疵的。
\r\n
\r\n       现在看来,她没有错,不过有张冠李戴之嫌。我不知道,是否有人第一次学到这里,不参考其他资料和明白人讲解的情况下,就能搞懂这个算法(我的意思是不仅是算法的大致思想,而是为什么定义和例子中next[j]=k(0≤k<j),而算法中next[j]=k(-1≤k<j))。 凭良心说:光看这个讲座,我就对这个教受十分敬佩,不仅讲课讲得好,声音悦耳,而且这门课讲得层次分明,恰到好处。在KMP这个问题上出了点小差错,可能是编书的时候,在这本书上抄下了例子,在那本书上抄下了算法,结果不怎么对得上号。因为我没找到原书,而据有的网友说,书上已不是这样,也许吧。说起来, 教授们研究的问题比这个高深不知多少倍,哪有时间推演这个小算法呢。总之,瑕不掩玉。
\r\n
\r\n 书归正传,下面给出我写的求第二种表示方法表示的模式值的函数,为了从S的任何位置开始匹配T,“当出现S[i] !=T[j]时,下一次的比较应该在S[i]和T[next[j]] 之间进行。”    定义next[0]=0 。
\r\n
\r\n  void myget_nextval(const char *T, int next[])
\r\n
\r\n {
\r\n
\r\n      // 求模式串T的next函数值(第二种表示方法)并存入数组 next。                
\r\n
\r\n      int j = 1, k = 0;
\r\n
\r\n      next[0] = 0;
\r\n
\r\n        while ( T[j] != '/0' )
\r\n
\r\n      {    
\r\n
\r\n                    if(T[j] == T[k])
\r\n
\r\n                    {
\r\n
\r\n                          next[j] = k;
\r\n
\r\n                          ++j; ++k;                 
\r\n
\r\n                    }
\r\n
\r\n                    else if(T[j] != T[0])
\r\n
\r\n                    {
\r\n
\r\n                   next[j] = k;
\r\n
\r\n                   ++j;
\r\n
\r\n                            k=0;
\r\n
\r\n                    }
\r\n
\r\n                    else
\r\n
\r\n                    {
\r\n
\r\n                           next[j] = k;
\r\n
\r\n                   ++j;
\r\n
\r\n                              k=1;
\r\n
\r\n                    }
\r\n
\r\n      }//while
\r\n
\r\n     for(int i=0;i<j;i++)
\r\n
\r\n      {
\r\n
\r\n             cout<<next[i];
\r\n
\r\n      }
\r\n
\r\n      cout<<endl;
\r\n
\r\n }// myget_nextval
\r\n
\r\n  
\r\n
\r\n       下面是模式值使用第二种表示方法的匹配函数(next[0]=0)
\r\n
\r\n int my_KMP(char *S, char *T, int pos)
\r\n
\r\n {
\r\n
\r\n int i = pos, j = 0;//pos(S 的下标0≤pos<StrLength(S))
\r\n
\r\n while ( S[i] != '/0' && T[j] != '/0' )
\r\n
\r\n {
\r\n
\r\n     if (S[i] == T[j] )
\r\n
\r\n      {
\r\n
\r\n          ++i;
\r\n
\r\n              ++j; // 继续比较后继字符
\r\n
\r\n      }
\r\n
\r\n    else             // a b a b c a a b c
\r\n
\r\n                     // 0 0 0 1 2 0 1 1 2
\r\n
\r\n    {              //-1 0 -1 0 2 -1 1 0 2
\r\n
\r\n       i++;
\r\n
\r\n      j = next[j];     /*当出现S[i] !=T[j]时,
\r\n
\r\n               下一次的比较应该在S[i]和T[next[j]] 之间进行。要求next[0]=0。
\r\n
\r\n 在这两个简单示范函数间使用全局数组next[]传值。*/
\r\n
\r\n    }
\r\n
\r\n }//while
\r\n
\r\n if ( T[j] == '/0' )
\r\n
\r\n     return (i-j); // 匹配成功
\r\n
\r\n else
\r\n
\r\n      return -1;
\r\n
\r\n } // my_KMP
\r\n
\r\n 六.后话--KMP的历史
\r\n
\r\n       Cook于1970年证明的一个理论得到,任何一个可以使用被称为下推自动机的计算机抽象模型来解决的问题,也可以使用一个实际的计算机(更精确的说,使用一个随机存取机)在与问题规模对应的时间内解决。特别地,这个理论暗示存在着一个算法可以在大约m+n的时间内解决模式匹配问题,这里m和n分别是存储文本和模式串数组的最大索引。Knuth 和Pratt努力地重建了 Cook的证明,由此创建了这个模式匹配算法。大概是同一时间,Morris在考虑设计一个文本编辑器的实际问题的过程中创建了差不多是同样的算法。这里可以看到并不是所有的算法都是“灵光一现”中被发现的,而理论化的计算机科学确实在一些时候会应用到实际的应用中。
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2935, 'use-datagrid-in-vb6-2', 'VB6中DataGrid的使用', '2012-05-22 22:04:34', '2019-03-25 21:29:22', '      概述:\r\nDataGrid 控 件是一种类似于电子数据表的绑定控件,可以显示一系列行和列来表示 Recordset 对象的记录和字段。可以使用 DataGrid 来创建一个允许最终用户阅读和写入到绝大多数数据库的应用程序。DataGrid 控件可以在设计时快速进行配置,只需少量代码或无需代码。当在设计时设置了 DataGrid 控件的 DataSource 属性后,就会用数据源的记录集来自动填充该控件,以及自动设置该控件的列标头。然后您就可以编辑该网格的列;删除、重新安排、添加列标头、或者调整任意一列的宽度。\r\n     在运行时,可以在程序中切换 DataSource 来察看不同的表,或者可以修改当前数据库 的查询,以返回一个不同的记录集合。\r\n      注意:DataGrid 控件与 Visual Basic 5.0中的 DBGrid 是代码兼容的,除了一个例外:DataGrid 控件不支持 DBGrid 的“解除绑定模式”概念。DBGrid 控件包括在 Visual Basic 的 Tools 目录中。\r\n      可能的用法:\r\n      查看和编辑在远程或本地数据库中的数据。\r\n      与另一个数据绑定的控件(诸如 DataList 控件)联合使用,使用 DataGrid控件来显示一个表的记录,这个表通过一个公共字段链接到由第二个数据绑定控件所显示的表。\r\n      使用 DataGrid 控件的设计时特性\r\n      可以不编写任何代码,只通过使用 DataGrid 控件的设计时特性来创建一个数据库应用程序。下面的说明概要地说明了在实现 DataGrid 控件的典型应用时的一般步骤。\r\n      实现一个 DataGrid 控件\r\n   首先,如果工具箱没有DataGrid空间,则需要引入,具体方法是:点击菜单项工程->部件,找到Microsoft ADO Data ControlMicrosoft DataGrid Control。勾上,并点击应用,然后关闭,这时,DataGrid控件和ADODC控件就会出现在工具箱了。\r\n\"\"\r\n      1. 在窗体上放置一个ADODC控件,并将其 ConnectionString 属性设置为数据源。\r\n\"\"\r\n      2. 在这个ADODC控件的RecordSource 属性中输入一条将返回一个记录集的 SQL 语句。例如,select Freq as 班次,StartTime as 发车时间,Start as 起点站,Stop as 终点站,TravelTime as 行车时间,RatedAmount as 额定数量,Ordered as 已订票人数,NoDisplay as 发车状态 from FreqInfo\r\n      4. 在窗体上放置一个 DataGrid 控件,并将其 DataSource 属性设置为这个ADODC控件的名称。\r\n\"\"\r\n      4. 右键单击该 DataGrid 控件,然后单击“检索字段”。\r\n      5. 右键单击该 DataGrid 控件,然后单击“编辑”。\r\n      6. 重新设置该网格的大小、删除或添加网格的列。\r\n      7. 右键单击该 DataGrid 控件,然后单击“属性”。\r\n      8. 使用“属性页”对话框来设置该控件的适当的属性,将该网格配置为所需的外观和行为。\r\n      在运行时更改显示的数据\r\n      在创建了一个使用设计时特性的网格后,也可以在运行时动态地更改该网格的数据源。下面介绍实现这一功能的通常方法。\r\n      更改 DataSource 的RecordSource\r\n      更改所显示的数据的最通常方法是改变该 DataSource 的查询。例如,如果DataGrid 控件使用一个ADO Data控件作为其 DataSource,则重写RecordSource和刷新该ADO Data 控件都将改变所显示的数据。\r\n      更改 DataSource\r\n      在 运行时,可以将 DataSource 属性重新设置为一个不同的数据源。例如,您可能具有若干个ADODC控件,每个控件连接不同的数据库, 或设置为不同的RecordSource属性。可以简单地将DataSource 从一个ADODC控件重新设置为另一 个ADODC控件。\r\n      重新绑定DataSource\r\n      当将DataGrid 控件用于一个远程数据库,诸如 SQLServer 时,可以改变表的结构。例如,可以给这个表添加一个字段。在这种情形下,可以 调用Rebind 方法根据新的结构来重新创建该网格。注意,如果已经在设计时改变了这个列的布局,DataGrid 控件将会试图重新创建当前的布局, 包括任何空的列。不过,通过首先调用 ClearFields 方法,可以强制该网格重新设置所有的列。\r\n      从DataGrid 返回值\r\n      在DataGrid 被连接到一个数据库后,可能想要监视用户单击了哪一个单元。可以使用 RowColChange 事件——而不是 Click 事件。如下所示:\r\nPrivate Sub DataGrid1_RowColChange(LastRow As Variant, ByVal LastCol As Integer)\r\n\' 显示用户所单击的单元的文字、行和列的信息。\r\nDebug.Print DataGrid1.Text; DataGrid1.Row; DataGrid1.Col\r\nEnd Sub\r\n      使用CellText和CellValue方法\r\n      当一个列使用 NumberFormat 属性设置格式后,CellText 和 CellValue 属性是很有用的。NumberFormat 属性不必更改实际的数据格式就可以更改任何包含数字的列的格式。例如,给定一个网格,其中包含一个名为 ProductID的、包含整数的列。下面的代码将 使 DataGrid 以\"P-0000\" 的格式来显示数据。换句话说,尽管在 ProductID 字段中所包含的实际数值为 \"3\",但该网格所显 示的值将是 \"P-0003\"。\r\nPrivate Sub Form_Load()\r\nDataGrid1.Columns(\"ProductID\").NumberFormat = \"P-0000\"\r\nEnd Sub\r\n      要返回数据库中所包含的实际值,应使用 CellValue 方法,如下所示:\r\nPrivate Sub DataGrid1_RowColChange(LastRow As Variant, ByVal LastCol As Integer)\r\nDebug.Print _\r\nDataGrid1.Columns(\"ProductID\").CellValue(DataGrid1.Bookmark)\r\nEnd Sub\r\n      注意:上面所用的CellValue和下面所用的CellText值,都需要将Bookmark 属性作为一个参数,功能才正确。\r\n      相反地,如果要返回该字段的格式化的值,应使用 CellText 方法:\r\nPrivate Sub DataGrid1_RowColChange(LastRow As Variant, ByVal LastCol As Integer)\r\nDebug.Print _\r\nDataGrid1.Columns(\"ProductID\").CellText(DataGrid1.Bookmark)\r\nEnd Sub\r\n      注意:上面的CellText 方法等价于使用 DataGrid 控件的Text 属性。\r\n\r\n      使用DataGrid 和ADODC控件创建一个简单的数据库应用程序\r\n      只使用一个 DataGrid 和一个ADODC控件,可以创建一个允许最终用户阅读和写入记录集的数据库应用程序。\r\n      使用 ADO 数据控件来创建一个简单的数据库应用程序步骤如下:\r\n      1. 在Visual Basic中创建一个新的标准的 EXE 工程。如果 DataGrid 控件不在“工具箱”中,则用右键单击“工具箱”,然后使用“部件”对话框来添加控件。同时也载入 ADO 控件。\r\n3. 在空窗体上各放置控件的一个实例(DataGrid控件和ADODC控件)。\r\n4. 将 ADODC控件的ConnectionString 属性设置为数据源。\r\n5. 设置 ADODC控件的 RecordSource 属性。在“属性”窗口中,单击“记录源”并输入一条 SQL 语句来填充 DataGrid控件。在本例中,输入“Select * From Products”。\r\n6. 将 DataGrid 控 件的 DataSource 属性设置为这个ADODC控件。\r\n7. 按 F5 键运行这个工程。\r\n\r\n      使用列\r\n      通过更改 DataSource 属性,可以动态地更改在 DataGrid 控件中显示的数据。例如,可以显示同一个数据库的不同表。如果这样做,则 DataGrid 控件将只根据默认的属性显示数据。\r\n      添加、删除或隐藏列\r\n      通过使用 Columns 集合和 Column 对象的属性和方法,可以在程序中添加、删除或隐藏列。\r\n      添加和删除一列\r\n      要在运行时添加一列,可以使用 Add 方法。如果首先声明一个变量,并将新对象赋给该变量,就可以用简明的代码设置各种属性。\r\nPrivate Sub AddColumn()\r\n\' 在最右边的位置添加一列。然后设置其 Visible、Width、\r\n\' Caption以及 Alignment 属性。DataField 属性则指定\r\n\' 该列将绑定到哪一个字段。\r\nDim c As Column\r\nSet c = DataGrid1.Columns.Add(DataGrid1.Columns.Count)\r\nWith c\r\n.Visible = True\r\n.Width = 1000\r\n.Caption = \"我的新列\"\r\n.DataField = Adodc1.Recordset.Fields(\"ProductName\").Name\r\n.Alignment = dbgRight\r\nEnd With\r\nEnd Sub\r\n      可以使用方法来删除任意一列。请确保使用 ColIndex 参数来指定要删除的列。下面的代码将删除被单击的列。\r\nPrivate Sub DataGrid1_HeadClick(ByVal ColIndex As Integer)\r\nDataGrid1.Columns.Remove ColIndex\r\nEnd Sub\r\n      隐藏一列\r\n      通过将 Visible 属性设置为 False,可以隐藏任意一列。当想要限制用户可以查看或编辑的列时这一功能特别有用。下面的示例在 Columns 集合中循环,隐藏除少数列之外的所有列。\r\nPrivate Sub HideColumns()\r\n\' 使用 DataField 属性来判别正在测试的是哪一列。\r\n\' 只显示三列:ProductName、UnitPrice以及\r\n\' UnitsInStock。\r\nDim c As Column\r\nFor Each c In DataGrid1.Columns\r\nSelect Case c.DataField\r\nCase \"ProductName\"\r\nc.Visible = True\r\nCase \"UnitPrice\"\r\nc.Visible = True\r\nCase \"UnitsInStock\"\r\nc.Visible = True\r\nc.Caption = \"In Stock\" \' 更改这个列的标头。\r\nCase Else \' 隐藏其它所有的列。\r\nc.Visible = False\r\nEnd Select\r\nNext c\r\nEnd Sub\r\n      操作DataGrid视图\r\n      一 个“拆分”的网格使最终用户对相同的数据可以拥有多个视图。例如,假设有一个由十个字段组成的大表。在这种情况下,在控件中察看的记录集将有十列宽,除非窗体非常宽,否则用户将无法同时看见所有列的内容。,而且,假设用户只对第一列和最后一列感兴趣(例如,第一列是名字,最后一列是电话号码)。为了能同时 看到在两端的列(不重新安排列的顺序),可以对网格进行拆分。\r\n      创建一个Split 对象\r\n      在设计时,可以创建一个拆分,具体步骤是:右键单击网格,单击“编辑”,再单击右键,然后单击“拆分”。通过右键单击该控件,并单击“属性”来显示“属性 页”对话框,可以编辑这个拆分。可以使用“拆分”选项卡来自定义拆分。要删除一个拆分,右键单击该拆分,并单击“删除”。\r\n      在运行时,最终用户也可以通过单击位于这个网格控件的左下边的右边的选项卡,以手工方式来拆分该网格(除非不允许这个操作)。\r\n      默认情况下,DataGrid 控件包含一个 Split 对象。防止最终用户添加拆分的代码为:\r\nDataGrid1.Splits(0).AllowSizing = False\r\n      在程序中添加和删除拆分\r\n      DataGrid 控件包含一个 Split 对象的集合。要在程序中添加拆分,可以使用 Add 方法,如下所示:\r\nDataGrid1.Splits.Add 1\r\n      注意 Add 方法需要新的拆分索引作为其参数。要添加一个拆分,应将这个索引参数设置为 Splits 集合的 Count 属性值。\r\n      使用 Split 集合的 Add 方法,可以在程序中按照实际需要添加拆分。由于添加多于两个以上的拆分将使网格很难使用,可以使用该集合的 Count 属性来限制拆分的数目。\r\nIf DataGrid1.Splits.Count < 3 Then \' 添加一个拆分。\r\nDataGrid1.Splits.Add DataGrid1.Splits.Count\r\nEnd If\r\n      使拆分同步\r\n      当拆分多于一个时,可能希望控制这些拆分如何滚动。例如,在一个具有三个拆分的网格中,可以决定只让第一个和第三个拆分同步,而让中间的拆分独立地滚动。要同步任何两个(或多个)拆分,只需将每个 Split 对象的 ScrollGroup 属性设置为同一个值。\r\n\' 使第一个和第三个 Split 对象同步。\r\nWith DataGrid1\r\n.Splits(0)\r\n.ScrollGroup = 1\r\n.Splits(1).ScrollGroup = 2\r\n.Splits(2).ScrollGroup = 1\r\nEnd With\r\n      通过设置 Scrollbars 属性,使同步的拆分组只显示一个滚卷条,从而进一步自定义拆分的外观。\r\n      控制Tab 键和箭头键的行为\r\n      使用 WrapCellPointer、TabAcrossSplits以及 TabAction 属性,可以决定当最终用户按下 tab 键或箭头键时网格的行为。\r\n      在这三个属性中,TabAction 属性级别最高,它决定 WrapCellPointer 和TabAcrossSplits 这两个属性是否能生效。 TabAction 有三个设置值:ControlNavigation、Column Navigation 和 Grid Navigation。 当该属性设置为 ControlNavigation 时,按 Tab 键根据 TabIndex 将焦点切换到下一个控件。这一设置优先 于 WrapCellPointer 和TabAcrossSplits。\r\n      WrapCellPointer 属 性决定在任何单个的拆分中 tab 键和箭头键的行为。如果该属性设置为 True,且当前单元位于最后一列,这时最终用户按 tab 键则使第一列的下 一行变成当前的单元。不过,如果当前单元位于最后一行的最后一列时,这时就没有地方可以“换行”。\r\n      TabAcrossSplits 属性决定当网格中存在两个或多个拆分时 tab 和箭头键的行为。如果该属性设置为 True,且当前单元位于任何一个拆分的最后一列,则按Tab或箭头键将使当前单元“跳” 到下一个拆分的第一列。当前单元仍保持相同的行位置。\r\n      注意:如果 WrapCellPointer 和 TabAcrossSplits 属性都设置为 True,则只有当前单元位于最后一个拆分的最后一列时才会换行。这时当前单元将换到第一个拆分的第一列中的下一行。\r\n      自定义列集合\r\n      每一个 Split 对象都有一个 Columns 属性,允许用户来操作一个 Column对象的集合。通过这样做,可以更改每个 Split 对象的外 观。例如,可以用一个拆分包含显示姓氏字段和名字字段的两个列,而第二个拆分则显示电话字段和地址字段。要实现这一目标,需要将其它的每一列 的 Visible 属性设置为 False,如下所示:\r\n\' 枚举 Columns 集合,对每一个 Column 对象的 DataField 属性\r\n\' 进行测试。如果测试失败,则隐藏这一列。\r\nDim i As Integer\r\n\' 隐藏除 ProductName 列之外的所有列。\r\nFor i = 0 To DataGrid1.Splits(0).Columns.Count - 1\r\nIf DataGrid1.Splits(0).Columns(i).DataField <> \"ProductName\" Then\r\nDataGrid1.Splits(0).Columns(i).Visible = False\r\nEnd If\r\nNext i\r\n\' 隐藏除 UnitPrice 列之外的所有列。\r\nFor i = 0 To DataGrid1.Splits(0).Columns.Count - 1\r\nIf DataGrid1.Splits(1).Columns(i).DataField <> \"UnitPrice\" Then\r\nDataGrid1.Splits(1).Columns(i).Visible = False\r\nEnd If\r\nNext I\r\n      使用 Bookmarks 和 SelBookmarks 跟踪记录\r\n      Bookmarks 和 SelBookmarks 提 供了标记记录的一种手段。当编写应用程序中的特定功能(诸如允许最终用户手工地选择多个不相邻的记录,进行所选记录的大批更新)时,这就很有必要。在这些 情形中,需要标记哪些记录已被选择,因此可以使用 SelBookmarks 集合及其属性。\r\n      有两个函数,分别是 CellText 和 CellValue 方法,需要标记才能正确执行。\r\n      标记用户的选择\r\n      SelBookmarks 集合包含所有选定的记录的书签。当最终用户手工选择记录时(即在单击时按住 CTRL 键),每一个选定的记录的书签都会加入到该集合中。使用标准的循环,用户可以知道已经选定了什么,也可以保存书签(因为可能需要恢复某个值),以及执行操作:\r\nDim i as Integer \' 计数器\r\nDim intCount As Integer\r\nintCount = DataGrid1.SelBookmarks.Count - 1\r\nReDim arrSelBK(intCount) \' 声明用于保存书签的数组。\r\nFor i = 0 To intCount\r\nArrSelBK(i) = DataGrid1.SelBookmarks(i)\r\n\' 在此处执行操作。如果该操作必须被\r\n\' 取消,则退出该循环,然后使用该数\r\n\' 组来取消这些更改。\r\nNext i\r\n      通过在程序中添加到 SelBookmarks 集合来选择记录\r\n      通过将记录添加到这个集合,也可以在程序中选定记录。例如,可能有一个显示指定的客户所有订货的网格。如果要高亮显示该客户花费超过 $100的所有记录,则对记录进行过滤,并将结果书签添加到 SelBookmarks 集合。\r\nDim rs As Recordset\r\nSet rs = Adodc1.Recordset\r\nWhile Not rs.EOF\r\nIf rs!SupplierID = 12 Then\r\nDataGrid1.SelBookmarks.Add rs.Bookmark\r\nEnd If\r\nrs.MoveNext\r\nWend\r\n      显示计算结果字段\r\n      假设在表中有一个名为 \"Price\" 的字段,并且想使用本地税率来计算表中每一项的税费。这就是一个计算结果字段,可以通过修改 DataSource 的查询来计算这个值,并把这个值返回给 DataGrid 控件。\r\n      与类模块一起使用 DataGrid 控件\r\n      如果想要访问以自定义格式或以 ODBC 驱动程序不直接支持的格式存放的数据,可以创建一个类来封装该数据。然后可以编写该类的自定义函数来检索这些数据。这样该类就变成了一种数据源,可以被任何数据使用者(如DataGrid 控件)使用。\r\n      在这个类模块的Initialize 事件中,首先通过声明一个作为 New ADODB.Recordset的变量,来创建一 个 ADODB recordset 对象。在创建了这个 recordset 对象后,再添加字段,每个数据源中的每个字段都要加入。然后使用合适的数 据填充这个记录集。\r\n      类模块有一个 GetDataMember 事件,只要当数据使用者(诸如 DataGrid 控件)需要数据时就产生该事件。在这个事件中,Data 参数被设置为在Initialize 事件中所创建的 recordset 对象。\r\n      如果要使用这个类模块,应创建一个具有一个 DataGrid 控件的窗体。在该窗体的 Load 事件的代码中,将该控件的 DataSource 属性设置为这个类。\r\n      注意:数据类模块在设计时是不可用的。例如,如果使用 DataGrid 控件,则当用户在“属性”窗口中单击“数据源”时,所有可用的数据源都会出现在一个下拉列表中。但其中不会有这个数据类模块,它只能在代码中设置。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2937, 'c-file-action-summary-2', 'C++文件操作总结', '2012-05-14 22:03:58', '2019-03-25 21:29:22', '一、ASCII 输出\r\n为了使用下面的方法, 你必须包含头文件<fstream.h>(笔者注:在标准C++中,已经使用<fstream>取代< fstream.h>,所有的C++标准头文件都是无后缀的)。这是 <iostream.h>的一个扩展集, 提供有缓冲的文件输入输出操作。事实上, <iostream.h> 已经被<fstream.h>包含了, 所以你不必包含所有这两个文件, 如果你想显式包含他们,那随便你。我们从文件操作类的设计开始, 我会讲解如何进行ASCII I/O操作。如果你猜是\"fstream,\" 恭喜你答对了! 但这篇文章介绍的方法,我们分别使用\"ifstream\"和\"ofstream\" 来作输入输出。\r\n如果你用过标准控制台流\"cin\"和 \"cout\" 那现在的事情对你来说很简单。 我们现在开始讲输出部分,首先声明一个类对象。\r\nofstream fout;\r\n这就可以了,不过你要打开一个文件的话, 必须像这样调用ofstream::open()。\r\nfout.open(\"C:/Documents and Settings/Administrator/桌面/output.txt\"); \r\n      你也可以把文件名作为构造参数来打开一个文件.\r\nofstream fout(\"C:/Documents and Settings/Administrator/桌面/output.txt\"); \r\n\"\"\r\n这是我们使用的方法, 因为这样创建和打开一个文件看起来更简单. 顺便说一句, 如果你要打开的文件不存在,它会为你创建一个, 所以不用担心文件创建的问题. 现在就输出到文件,看起来和\"cout\"的操作很像。对不了解控制台输出\"cout\"的人, 这里有个例子。\r\nint num = 247;\r\nchar name[] = \"www.xinvalue.com\";\r\nfout << \"新价值网已经诞生了\" << num << \"天!n\";\r\nfout << \"新价值网的域名是: \" << name << \"n\";\r\n现在保存文件,你必须关闭文件,或者回写文件缓冲. 文件关闭之后就不能再操作了, 所以只有在你不再操作这个文件的时候才调用它,它会自动保存文件。回写缓冲区会在保持文件打开的情况下保存文件, 所以只要有必要就使用它。 回写看起来像另一次输出, 然后调用方法关闭。像这样:\r\nfout << flush;\r\nfout.close(); \r\n现在你用文本编辑器打开文件,内容看起来是这样:\r\n\"\"\r\n很简单吧!\r\n现在继续文件输入, 需要一点技巧, 所以先确认你已经明白了流操作,对 \"<<\" 和\">>\" 比较熟悉了, 因为你接下来还要用到他们。\r\n\r\n二、ASCII 输入\r\n输入和\"cin\" 流很像. 和刚刚讨论的输出流很像, 但你要考虑几件事情。在我们开始复杂的内容之前, 先看一个文本:\r\n新价值网\r\n编程技术交流\r\n软件源码共享\r\n网站 设计开发\r\n为了打开这个文件,你必须创建一个in-stream对象,像这样:\r\nifstream fin(\"C:/Documents and Settings/Administrator/桌面/input.txt\"); \r\n现在读入前四行. 你还记得怎么用\"<<\" 操作符往流里插入变量和符号吧?好,在 \"<<\" (插入)操作符之后,是\">>\" (提取) 操作符. 使用方法是一样的. \r\nchar sentence1[100];\r\nchar sentence2[100];\r\nchar sentence3[100];\r\nchar sentence4[100];\r\nfin >> sentence1;\r\nfin >> sentence2;\r\nfin >> sentence3;\r\nfin >> sentence4;\r\n      它是如何运作的呢? 文件的每个空白之后, \">>\" 操作符会停止读取内容, 直到遇到另一个>>操作符. 因为我们读取的每一行都被换行符分割开(是空白字符), \">>\" 操作符只把这一行的内容读入变量。但是,可别忘了文件的最后一行。\r\n网站 设计开发\r\n如果你想把整行读入一个char数组, 我们没办法用\">>\"操作符,因为每个单词之间的空格(空白字符)会中止文件的读取。\r\n我们想包含整个句子, \"网站 设计开发\" 但是因为空白, 现在它只包含了\"网站\".\r\n\"\"\r\n很明显, 肯定有读取整行的方法, 它就是getline()。这就是我们要做的。\r\nfin.getline(sentence1, 100); \r\nfin.getline(sentence2, 100); \r\nfin.getline(sentence3, 100); \r\nfin.getline(sentence4, 100); \r\n      这是函数参数. 第一个参数显然是用来接受的char数组. 第二个参数是在遇到换行符之前,数组允许接受的最大元素数量. 现在我们得到了想要的结果:“网站 设计开发”。\r\n\"\"\r\n你应该已经知道如何读取和写入ASCII文件了。但我们还不能罢休,因为二进制文件还在等着我们。\r\n\r\n三、二进制输入输出\r\n二进制文件会复杂一点, 但还是很简单的。 首先你要注意我们不再使用插入和提取操作符(笔者注:<< 和 >> 操作符). 你可以这么做,但它不会用二进制方式读写。你必须使用read() 和write() 方法读取和写入二进制文件. 创建一个二进制文件, 看下一行。\r\nofstream fout(\"C:/Documents and Settings/Administrator/桌面/file.dat\", ios::binary);\r\n这会以二进制方式打开文件, 而不是默认的ASCII模式。首先从写入文件开始。函数write() 有两个参数。 第一个是指向对象的char类型的指针, 第二个是对象的大小(笔者注:字节数)。 为了说明,看例子。\r\nint number = 30;\r\nfout.write((char *)(&number), sizeof(number)); \r\n第一个参数写做\"(char *)(&number)\". 这是把一个整型变量转为char *指针。如果你不理解,可以立刻翻阅C++的书籍,如果有必要的话。第二个参数写作\"sizeof(number)\"。sizeof() 返回对象大小的字节数. 就是这样!\r\n  二进制文件最好的地方是可以在一行把一个结构写入文件。 如果说,你的结构有12个不同的成员。 用ASCII文件,你不得不每次一条的写入所有成员。 但二进制文件替你做好了。 看这个。\r\nstruct OBJECT {\r\nint number;\r\nchar letter;\r\n} obj;\r\nobj.number = 15;\r\nobj.letter = ‘M’;\r\nfout.write((char *)(&obj), sizeof(obj));\r\n这样就写入了整个结构! 接下来是输入. 输入也很简单,因为read()函数的参数和 write()是完全一样的, 使用方法也相同。\r\nifstream fin(\"C:/Documents and Settings/Administrator/桌面/file.dat\", ios::binary);\r\nfin.read((char *)(&obj), sizeof(obj)); \r\n我不多解释用法, 因为它和write()是完全相同的。二进制文件比ASCII文件简单, 但有个缺点是无法用文本编辑器编辑。 接着, 我解释一下ifstream 和ofstream 对象的其他一些方法作为结束.\r\n\r\n四、更多方法\r\n我已经解释了ASCII文件和二进制文件, 这里是一些没有提及的底层方法。\r\n\r\n检查文件\r\n你已经学会了open()close() 方法, 不过这里还有其它你可能用到的方法。\r\n方法good() 返回一个布尔值,表示文件打开是否正确。\r\n类似的,bad() 返回一个布尔值表示文件打开是否错误。 如果出错,就不要继续进一步的操作了。\r\n最后一个检查的方法是fail(), 和bad()有点相似, 但没那么严重。\r\n\r\n读文件\r\n方法get() 每次返回一个字符。\r\n方法ignore(int,char) 跳过一定数量的某个字符, 但你必须传给它两个参数。第一个是需要跳过的字符数。 第二个是一个字符, 当遇到的时候就会停止。 例子,\r\nfin.ignore(100, ‘/n’); \r\n会跳过100个字符,或者不足100的时候,跳过所有之前的字符,包括 ‘/n’。\r\n方法peek() 返回文件中的下一个字符, 但并不实际读取它。所以如果你用peek() 查看下一个字符, 用get() 在peek()之后读取,会得到同一个字符, 然后移动文件计数器。\r\n方法putback(char) 输入字符, 一次一个到流中。我没有见到过它的使用,但这个函数确实存在。\r\n\r\n写文件\r\n只有一个你可能会关注的方法?那就是 put(char), 它每次向输出流中写入一个字符。\r\n\r\n打开文件\r\n当我们用这样的语法打开二进制文件:\r\nofstream fout(\"C:/Documents and Settings/Administrator/桌面/file.dat\", ios::binary);\r\n      \"ios::binary\"是你提供的打开选项的额外标志. 默认的, 文件以ASCII方式打开, 不存在则创建, 存在就覆盖. 这里有些额外的标志用来改变选项。\r\nios::app 添加到文件尾\r\nios::ate 把文件标志放在末尾而非起始。\r\nios::trunc 默认. 截断并覆写文件。\r\nios::nocreate 文件不存在也不创建。\r\nios::noreplace 文件存在则失败。\r\n\r\n文件状态\r\n我用过的唯一一个状态函数是eof(), 它返回是否标志已经到了文件末尾。 我主要用在循环中。 例如, 这个代码断统计小写‘e’ 在文件中出现的次数。\r\nifstream fin(\"C:/Documents and Settings/Administrator/桌面/file.txt\");\r\nchar ch;\r\nint counter;\r\nwhile (!fin.eof()) {\r\nch = fin.get();\r\nif (ch == ‘e’) counter++;\r\n}\r\nfin.close();\r\n我从未用过这里没有提到的其他方法。 还有很多方法,但是他们很少被使用。参考C++书籍或者文件流的帮助文档来了解其他的方法。\r\n\r\n结论\r\n你应该已经掌握了如何使用ASCII文件和二进制文件。有很多方法可以帮你实现输入输出,尽管很少有人使用他们。我知道很多人不熟悉文件I/O操作,我希望这篇文章对你有所帮助。 每个人都应该知道. 文件I/O还有很多显而易见的方法,例如包含文件 <stdio.h>. 我更喜欢用流是因为他们更简单。 祝所有读了这篇文章的人好运, 也许以后我还会为你们写些东西。\r\n\r\n无论读写都要包含<fstream>头文件\r\n 读:从外部文件中将数据读到程序中来处理\r\n对于程序来说,是从外部读入数据,因此定义输入流,即定义输入流对象:ifsteam infile,infile就是输入流对象。\r\n这个对象当中存放即将从文件读入的数据流。假设有名字为myfile.txt的文件,存有两行数字数据,具体方法:\r\nint a,b;\r\nifstream infile;\r\ninfile.open(\"myfile.txt\");      //注意文件的路径\r\ninfile>>a>>b;                   //两行数据可以连续读出到变量里\r\ninfile.close()\r\n\r\n如果是个很大的多行存储的文本型文件可以这么读:\r\nchar buf[1024];                //临时保存读取出来的文件内容\r\nstring message;\r\nifstream infile;\r\ninfile.open(\"myfile.js\");\r\nif(infile.is_open())          //文件打开成功,说明曾经写入过东西\r\n{\r\nwhile(infile.good() && !infile.eof())\r\n{\r\nmemset(buf,0,1024);\r\ninfile.getline(buf,1204);\r\nmessage = buf;\r\n......                     //这里可能对message做一些操作\r\ncout<<message<<endl;\r\n}\r\ninfile.close();\r\n}\r\n\r\n    写:将程序中处理后的数据写到文件当中\r\n对程序来说是将数据写出去,即数据离开程序,因此定义输出流对象ofstream outfile,outfile就是输出流对象,这个对象用来存放将要写到文件当中的数据。具体做法:\r\nofstream outfile;\r\noutfile.open(\"myfile.bat\");  //myfile.bat是存放数据的文件名\r\nif(outfile.is_open())\r\n{\r\noutfile<<message<<endl;    //message是程序中处理的数据\r\noutfile.close();\r\n}\r\nelse\r\n{\r\ncout<<\"不能打开文件!\"<<endl;\r\n}\r\n\r\nc++对文件的读写操作的例子\r\n/*从键盘读入一行字符,把其中的字母依次放在磁盘文件fa2.dat中,再把它从磁盘文件读入程序,将其中的小写字母改成大写字母,再存入磁盘fa3.dat中*/\r\n#i nclude<fstream>\r\n#i nclude<iostream>\r\n#i nclude<cmath>\r\nusing namespace std;\r\n//从键盘上读取字符的函数\r\nvoid read_save(){\r\nchar c[80];\r\nofstream outfile(\"f1.dat\");//以输出方工打开文件\r\nif(!outfile){\r\ncerr<<\"open error!\"<<endl;//注意是用的是cerr\r\nexit(1);\r\n}\r\ncin.getline(c,80);//从键盘读入一行字符\r\nfor(int i=0;c[i]!=0;i++) //对字符一个一个的处理,直到遇到\'/0\'为止\r\nif(c[i]>=65&&c[i]<=90||c[i]>=97&&c[i]<=122){//保证输入的字符是字符\r\noutfile.put(c[i]);//将字母字符存入磁盘文件\r\ncout<<c[i]<<\"\";\r\n}\r\ncout<<endl;\r\noutfile.close();\r\n}\r\nvoid creat_data(){\r\nchar ch;\r\nifstream infile(\"f1.dat\",ios::in);//以输入的方式打开文件\r\nif(!infile){\r\ncerr<<\"open error!\"<<endl;\r\nexit(1);\r\n}\r\nofstream outfile(\"f3.dat\");//定义输出流f3.dat文件\r\nif(!outfile){\r\ncerr<<\"open error!\"<<endl;\r\nexit(1);\r\n}\r\nwhile(infile.get(ch)){//当读取字符成功时\r\nif(ch<=122&&ch>=97)\r\nch=ch-32;\r\noutfile.put(ch);\r\ncout<<ch;\r\n}\r\ncout<<endl;\r\ninfile.close();\r\noutfile.close();\r\n}\r\nint main(){\r\nread_save();\r\ncreat_data();\r\nsystem(\"pause\");\r\nreturn 0;\r\n}', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2938, 'cpp-inline', 'C++中内置函数(inline)详解', '2012-05-14 06:48:02', '2019-03-25 21:29:22', '
\r\n 内联函数简介:
\r\n      内联函数(inline function与一般的函数不同,不是在调用时发生控制转移,而是在编译阶段将函数体嵌入到每一个调用语句中
\r\n      内联函数(inline function)与编译器的工作息息相关编译器会将程序中出现内联函数的调用表达式用内联函数的函数体来替换
\r\n
\r\n
\r\n  \r\n
\r\n
\r\n
\r\n
\r\n
\r\n Cpp代码示例1: 
\r\n/**
\r\n*在类里定义的成员函数会被隐含指定为内置函数
\r\n*/  
\r\n#include \"stdafx.h\"
\r\n#include <iostream>
\r\n#include <string>
\r\n
\r\nusing namespace std;
\r\n
\r\nclass CStudent
\r\n{
\r\npublic:
\r\n    void display()
\r\n    {
\r\n        cout<<\"name:\"<<name<<endl;
\r\n    }
\r\n    string name;
\r\n};
\r\n
\r\nint main(int argc, char* argv[])
\r\n{
\r\n    CStudent myStudent;
\r\n    myStudent.name=\"Erin\";
\r\n    myStudent.display();
\r\n    return 0;
\r\n}

\r\n
\r\nCpp代码示例2:  \r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n /**
\r\n*类外定义的函数用inline指定为内置函数
\r\n*/
\r\n
\r\n#include \"stdafx.h\"
\r\n#include <iostream>
\r\n#include <string>
\r\n
\r\nusing namespace std;
\r\n
\r\nclass CStudent
\r\n{
\r\npublic:
\r\n    inline void display();
\r\n    string name;
\r\n};
\r\n
\r\ninline void CStudent::display()
\r\n{
\r\n    cout<<\"name:\"<<name<<endl;
\r\n}
\r\n
\r\nint main(int argc, char* argv[])
\r\n{
\r\n    CStudent myStudent;
\r\n    myStudent.name=\"Erin\";
\r\n    myStudent.display();
\r\n    return 0;
\r\n}
\r\n
\r\n
\r\n
\r\n
\r\nCpp代码示例3: 
\r\n/**
\r\n*无内置函数
\r\n*既没有在类内定义函数,也没有用inline在类外定义函数
\r\n*/
\r\n
\r\n#include \"stdafx.h\"
\r\n#include <iostream>
\r\n#include <string>
\r\n
\r\nusing namespace std;
\r\n
\r\nclass CStudent
\r\n{
\r\npublic:
\r\n    void display();
\r\n    string name;
\r\n};
\r\n
\r\nvoid CStudent::display()
\r\n{
\r\n    cout<<\"name:\"<<name<<endl;
\r\n}
\r\n
\r\nint main(int argc, char* argv[])
\r\n{
\r\n    CStudent myStudent;
\r\n    myStudent.name=\"Erin\";
\r\n    myStudent.display();
\r\n    return 0;
\r\n}

\r\n \r\n
\r\n
\r\n 内联函数的优点:\r\n
\r\n
\r\n      首先来看函数调用的实质,其实是将程序执行转移到被调用函数所存放的内存地址,将函数执行完后,在返回到执行此函数前的地方。这种转移操作需要保护现场 (包括各种函数的参数的进栈操作),在被调用函数代码执行完后,再恢复现场。但是保护现场和恢复现场需要较大的资源开销。\r\n
\r\n
\r\n      特别是对于一些较小的调用函数来说(如上边代码中的display()函数),若是频繁调用,函数调用过程甚至可能比函数执行过程需要的系统资源更多。所以引入内联函数,可以让程序执行效率更高。\r\n
\r\n
\r\n  \r\n
\r\n
\r\n 内联函数的缺点:\r\n
\r\n
\r\n       如果调用内联函数的地方过多,也可能造成代码膨胀。毕竟,编译器会把内联函数的函数体嵌入到每一个调用了它的地方,重复地嵌入。\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2939, 'enumerated-types-in-c-enum-details', 'C#中的枚举类型(Enum)详解', '2012-05-13 02:35:12', '2019-03-25 21:29:22', '
枚举的定义\r\n==========\r\n枚举类型(enum)声明为一组相关的符号常数,定义了一个类型名称。枚举用于“多项选择”场合,就是程序运行时从编译时已经设定的固定数目的“选择”中做出决定。\r\n\r\n枚举类型(也称为枚举)为定义一组可以赋给变量的命名整数常量提供了一种有效的方法。例如,假设您必须定义一个变量,该变量的值表示一周中的一天。该变量只能存储七个有意义的值。若要定义这些值,可以使用枚举类型。枚举类型是使用 enum 关键字声明的。 \r\n```csharp\r\nenum Days { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday };\r\n```\r\n默认情况下,枚举中每个元素的基础类型是int。可以使用冒号指定另一种整数值类型。\r\n如果不为枚举数列表中的元素指定值,则它们的值将以 1 为增量自动递增。在前面的示例中,Days.Sunday 的值为 0,Days.Monday 的值为 1,依此类推。创建新的 Days 对象时,如果不显式为其赋值,则它将具有默认值 Days.Sunday (0)。创建枚举时,应选择最合理的默认值并赋给它一个零值。这便使得只要在创建枚举时未为其显式赋值,则所创建的全部枚举都将具有该默认值。枚举中大小写敏感,但是建议不要这样。\r\n\r\n枚举的优点\r\n==========\r\n1、枚举可以使代码更易于维护,有助于确保给变量指定合法的、期望的值。\r\n\r\n2、枚举使代码更清晰,允许用描述性的名称表示整数值,而不是用含义模糊的数来表示\r\n\r\n3、枚举使代码更易于键入。在给枚举类型的实例赋值时,Visual Studio会通过IntelliSense弹出一个包含可接受值的列表框,减少了按键次数,并能够让我们回忆起可能的值。\r\n\r\n枚举方法\r\n========\r\n1、获取枚举字符串\r\n```cahsrp\r\nTimeOfDay time = TimeOfDay.Afternoon;\r\nConsole.WriteLine(time.ToString());\r\n//输出:Afternoon\r\n```\r\n2、Enum.Parse()方法。这个方法带3个参数,第一个参数是要使用的枚举类型。其语法是关键字typeof后跟放在括号中的枚举类名。第二个参数是要转换的字符串,第三个参数是一个bool,指定在进行转换时是否忽略大小写。最后,注意Enum.Parse()方法实际上返回一个对象引用—— 我们需要把这个字符串显式转换为需要的枚举类型(这是一个取消装箱操作的例子)。对于上面的代码,将返回1,作为一个对象,对应于TimeOfDay.Afternoon的枚举值。在显式转换为int时,会再次生成1。\r\n```csharp\r\nTimeOfDay time2 = (TimeOfDay) Enum.Parse(typeof(TimeOfDay), \"afternoon\", true);\r\nConsole.WriteLine((int)time2);//输出1\r\n```\r\n\r\n3、得到枚举的某一值对应的名称\r\nlbOne.Text = Enum.GetName(typeof(TimeOfDay), 0);\r\n\r\n4、得到枚举的所有的值 \r\n```csharp\r\nforeach (int i in Enum.GetValues(typeof(TimeOfDay)))\r\n	lbValues.Text += i.ToString();\r\n```\r\n\r\n5、枚举所有的名称 \r\n```csharp\r\nforeach(string temp in Enum.GetNames(typeof(TimeOfDay)))\r\n	lbNames.Text+=temp;\r\n```\r\n\r\n枚举和常量\r\n==========\r\n优先考虑枚举。\r\n在[C#](http://www.jucoder.com/bbs/forum-0-20101-201.html)中, 枚举的真正强大之处是它们在后台会实例化为派生于基类System.Enum的结构。这表示可以对它们调用方法,执行有用的任务。注意因为.NET Framework的执行方式,在语法上把枚举当做结构是不会有性能损失的。实际上,**一旦代码编译好,枚举就成为基本类型,与int和float类似。**\r\n但是在实际应用中,你也许会发现,我们经常用英语定义枚举类型,因为开发工具本来就是英文开发的,美国人用起来,就直接能够明白枚举类型的含义。其实, 我们在开发的时候就多了一步操作,需要对枚举类型进行翻译。没办法,谁让编程语言是英语写的,如果是汉语写的,那我们也就不用翻译了,用起枚举变得很方便 了。举个简单的例子,TimeOfDay.Morning一看到Morning,美国人就知道是上午,但是对于中国的使用者来说,可能有很多人就看不懂, 这就需要我们进行翻译、解释,就向上面的getTimeOfDay()的方法,其实就是做了翻译工作。所以,在使用枚举的时候,感觉到并不是很方便,有的 时候我们还是比较乐意创建常量,然后在类中,声明一个集合来容纳常量和其意义。\r\n\r\n使用常量定义:这种方法固然可行,但是不能保证传入的参数day就是实际限定的。\r\n```csharp\r\nusing System;\r\nusing System.Collections.Generic;\r\npublic class TimesOfDay\r\n{\r\n    public const int Morning = 0;\r\n    public const int Afternoon = 1;\r\n    public const int Evening = 2;\r\n    public static Dictionary list;\r\n    ///\r\n\r\n    /// 获得星期几\r\n    ///\r\n    ///\r\n    ///\r\n    public static string getTimeNameOfDay(int time)\r\n    {\r\n        if (list == null || list.Count <= 0)\r\n        {\r\n            list = new Dictionary();\r\n            list.Add(Morning, \"上午\");\r\n            list.Add(Afternoon, \"下午\");\r\n            list.Add(Evening, \"晚上\");\r\n        }\r\n\r\n        return list[time];\r\n    }\r\n    }\r\n```\r\n\r\n希望能够找到一种比较好的方法,将枚举转为我们想要的集合。搜寻了半天终于找到了一些线索。通过反射,得到针对某一枚举类型的描述。\r\n\r\n枚举的定义中加入描述 \r\n```csharp\r\n    using System;\r\n\r\n    using System.ComponentModel;\r\n\r\n    public enum TimeOfDay\r\n\r\n    {\r\n\r\n\r\n        [Description(\"上午\")]\r\n        Moning,\r\n        [Description(\"下午\")]\r\n        Afternoon,\r\n        [Description(\"晚上\")]\r\n        Evening,\r\n    };\r\n\r\n       获得值和表述的键值对\r\n            ///\r\n            /// 从枚举类型和它的特性读出并返回一个键值对\r\n            ///\r\n            /// Type,该参数的格式为typeof(需要读的枚举类型)\r\n            /// 键值对\r\n            public static NameValueCollection GetNVCFromEnumValue(Type enumType)\r\n            {\r\n                NameValueCollection nvc = new NameValueCollection();\r\n                Type typeDescription = typeof(DescriptionAttribute);\r\n                System.Reflection.FieldInfo[] fields = enumType.GetFields();\r\n                string strText = string.Empty;\r\n                string strValue = string.Empty;\r\n                foreach (FieldInfo field in fields)\r\n                {\r\n                    if (field.FieldType.IsEnum)\r\n                    {\r\n                        strValue = ((int)enumType.InvokeMember(field.Name, BindingFlags.GetField, null, null, null)).ToString();\r\n                        object[] arr = field.GetCustomAttributes(typeDescription, true);\r\n                        if (arr.Length > 0)\r\n                        {\r\n                            DescriptionAttribute aa = (DescriptionAttribute)arr[0];\r\n                            strText = aa.Description;\r\n                        }\r\n                        else\r\n                        {\r\n                            strText = field.Name;\r\n                        }\r\n                        nvc.Add(strText, strValue);\r\n                    }\r\n                }\r\n                return nvc;\r\n            }\r\n\r\n    public enum TimeOfDay\r\n    {\r\n        Moning = 0,\r\n        Afternoon = 1,\r\n        Evening = 2,\r\n    };\r\n```\r\n\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2950, 'business-primary-keys-in-the-database-and-logical-primary-keys-composite-primary-keys-details-2', '数据库中业务主键、逻辑主键和复合主键详解', '2012-05-02 05:14:29', '2019-03-25 21:29:22', '      在数据库的创建中,主键起着唯一表示元素的作用,其地位不言而喻。对逻辑主键、业务主键和复合主键的选择,将直接决定项目的性能。下面是自己基于 SQL Server 做的一些总结,其他数据库(Oracle、MySQL、DB2、......)应该也类似。\r\n
\r\n\r\n定义:\r\n\r\n主键(PRIMARY KEY):表通常具有包含唯一标识表中每一行的值的一列或一组列。这样的一列或多列称为表的主键 (PK),用于强制表的实体完整性。\r\n\r\n外键(FOREIGN KEY):外键 (FK) 是用于建立和加强两个表数据之间的链接的一列或多列。在外键引用中,当一个表的列被引用作为另一个表的主键值的列时,就在两表之间创建了链接。这个列就成为第二个表的外键。\r\n\r\n聚集索引:聚集索引基于数据行的键值在表内排序和存储这些数据行。每个表只能有一个聚集索引,因为数据行本身只能按一个顺序存储。\r\n\r\n非聚集索引:非聚集索引包含索引键值和指向表数据存储位置的行定位器。可以对表或索引视图创建多个非聚集索引。通常,设计非聚集索引是为改善经常使用的、没有建立聚集索引的查询的性能。\r\n\r\n自动编号列和标识符列:对于每个表,均可创建一个包含系统生成的序号值的标识符列,该序号值以唯一方式标识表中的每一行。\r\n\r\n业务主键(自然主键):在数据库表中把具有业务逻辑含义的字段作为主键,称为“自然主键(Natural Key)”。\r\n\r\n逻辑主键(代理主键):在数据库表中采用一个与当前表中逻辑信息无关的字段作为其主键,称为“代理主键”。\r\n\r\n复合主键(联合主键):通过两个或者多个字段的组合作为主键。\r\n\r\n原理分析:\r\n\r\n      使用逻辑主键的主要原因是,业务主键一旦改变则系统中关联该主键的部分的修改将会是不可避免的,并且引用越多改动越大。而使用逻辑主键则只需要修改 相应的业务主键相关的业务逻辑即可,减少了因为业务主键相关改变对系统的影响范围。业务逻辑的改变是不可避免的,因为“永远不变的是变化”,没有任何一个 公司是一成不变的,没有任何一个业务是永远不变的。最典型的例子就是身份证升位和驾驶执照号换用身份证号的业务变更。而且现实中也确实出现了身份证号码重复的情况,这样如果用身份证号码作为主键也带来了难以处理的情况。当然应对改变,可以有很多解决方案,方案之一是做一新系统与时俱进,这对软件公司来说确实是件好事。\r\n\r\n      使用逻辑主键的另外一个原因是,业务主键过大,不利于传输、处理和存储。我认为一般如果业务主键超过8字节就应该考虑使用逻辑主键了,因为int是 4字节的,bigint是8字节的,而业务主键一般是字符串,同样是 8 字节的 bigint 和 8 字节的字符串在传输和处理上自然是 bigint 效率更高一些。想象一下 code == \"12345678\" 和 id == 12345678 的汇编码的不同就知道了。当然逻辑主键不一定是 int 或者 bigint ,而业务主键也不一定是字符串也可以是 int 或 datetime 等类型,同时传输的也不一定就是主键,这个就要具体分析了,但是原理类似,这里只是讨论通常情况。同时如果其他表需要引用该主键的话,也需要存储该主键, 那么这个存储空间的开销也是不一样的。而且这些表的这个引用字段通常就是外键,或者通常也会建索引方便查找,这样也会造成存储空间的开销的不同,这也是需 要具体分析的。\r\n\r\n      使用逻辑主键的再一个原因是,使用 int 或者 bigint 作为外键进行联接查询,性能会比以字符串作为外键进行联接查询快。原理和上面的类似,这里不再重复。\r\n\r\n使用逻辑主键的再一个原因是,存在用户或维护人员误录入数据到业务主键中的问题。例如错把 RMB 录入为 RXB ,相关的引用都是引用了错误的数据,一旦需要修改则非常麻烦。如果使用逻辑主键则问题很好解决,如果使用业务主键则会影响到其他表的外键数据,当然也可以 通过级联更新方式解决,但是不是所有都能级联得了的。\r\n\r\n      使用业务主键的主要原因是,增加逻辑主键就是增加了一个业务无关的字段,而用户通常都是对于业务相关的字段进行查找(比如员工的工号,书本的 ISBN No. ),这样我们除了为逻辑主键加索引,还必须为这些业务字段加索引,这样数据库的性能就会下降,而且也增加了存储空间的开销。所以对于业务上确实不常改变的 基础数据而言,使用业务主键不失是一个比较好的选择。另一方面,对于基础数据而言,一般的增、删、改都比较少,所以这部分的开销也不会太多,而如果这时候 对于业务逻辑的改变有担忧的话,也是可以考虑使用逻辑主键的,这就需要具体问题具体分析了。\r\n\r\n      使用业务主键的另外一个原因是,对于用户操作而言,都是通过业务字段进行的,所以在这些情况下,如果使用逻辑主键的话,必须要多做一次映射转换的动 作。我认为这种担心是多余的,直接使用业务主键查询就能得到结果,根本不用管逻辑主键,除非业务主键本身就不唯一。另外,如果在设计的时候就考虑使用逻辑 主键的话,编码的时候也是会以主键为主进行处理的,在系统内部传输、处理和存储都是相同的主键,不存在转换问题。除非现有系统是使用业务主键,要把现有系 统改成使用逻辑主键,这种情况才会存在转换问题。暂时没有想到还有什么场景是存在这样的转换的。\r\n\r\n      使用业务主键的再一个原因是,对于银行系统而言安全性比性能更加重要,这时候就会考虑使用业务主键,既可以作为主键也可以作为冗余数据,避免因为使 用逻辑主键带来的关联丢失问题。如果由于某种原因导致主表和子表关联关系丢失的话,银行可是会面临无法挽回的损失的。为了杜绝这种情况的发生,业务主键需 要在重要的表中有冗余存在,这种情况最好的处理方式就是直接使用业务主键了。例如身份证号、存折号、卡号等。所以通常银行系统都要求使用业务主键,这个需 求并不是出于性能的考虑而是出于安全性的考虑。\r\n\r\n      使用复合主键的主要原因和使用业务主键是相关的,通常业务主键只使用一个字段不能解决问题,那就只能使用多个字段了。例如使用姓名字段不够用了,再 加个生日字段。这种使用复合主键方式效率非常低,主要原因和上面对于较大的业务主键的情况类似。另外如果其他表要与该表关联则需要引用复合主键的所有字 段,这就不单纯是性能问题了,还有存储空间的问题了,当然你也可以认为这是合理的数据冗余,方便查询,但是感觉有点得不偿失。\r\n\r\n      使用复合主键的另外一个原因是,对于关系表来说必须关联两个实体表的主键,才能表示它们之间的关系,那么可以把这两个主键联合组成复合主键即可。如 果两个实体存在多个关系,可以再加一个顺序字段联合组成复合主键,但是这样就会引入业务主键的弊端。当然也可以另外对这个关系表添加一个逻辑主键,避免了 业务主键的弊端,同时也方便其他表对它的引用。\r\n\r\n      综合来说,网上大多数人是倾向于用逻辑主键的,而对于实体表用复合主键方式的应该没有多少人认同。支持业务主键的人通常有种误解,认为逻辑主键必须对用户来说有意义,其实逻辑主键只是系统内部使用的,对用户来说是无需知道的。\r\n\r\n结论或推论:\r\n\r\n1、尽量避免使用业务主键,尽量使用逻辑主键。\r\n\r\n2、如果要使用业务主键必须保证业务主键相关的业务逻辑改变的概率为0,并且业务主键不太大,并且业务主键不能交由用户修改。\r\n\r\n3、除关系表外,尽量不使用复合主键。\r\n\r\n使用逻辑主键的最佳实践指南:\r\n\r\n1、足够用就好。系统使用的生命周期以100年为限,逻辑主键数据类型采用下表规则,如果不确定则使用int类型。\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
数据量数据类型数据大小生成频率备注
< 128tinyint1 字节1条/年频率过低,不太靠谱,不建议采用
< 3 万smallint2 字节27条/月频率较低,慎用
< 21 亿int4 字节40条/分钟能满足大部分情况
< 922 亿亿bigint8 字节292万条/毫秒能满足绝大部分情况 
>= 922 亿亿uniqueidentifier16 字节100亿用户同时每毫秒生成10亿条,可以连续生成10亿年可用于分布式、高并发的应用
\r\n2、一般采用自增长方式或NewID()方式。\r\n\r\n3、主键字段名称一般采用“表名ID”方式,方便识别和表联接。\r\n\r\n4、如果表存在分布式应用,则可以考虑采用不同起始值,相同步长方式自增。例如有3个部署在不同地方的库,则可以如下设计:\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
起始值步长
110
210
310
\r\n步长统一设置10是为了方便日后扩展,这样不同库之间也能保持主键唯一性了,也方便合并。\r\n\r\n5、如果存在高并发性需求或数据表迁移需求,可以考虑使用uniqueidentifier类型,并使用NewID()函数。\r\n\r\n6、可以考虑对业务主键建立唯一性索引,以实现业务主键唯一性的业务需求。\r\n\r\n7、如果需要考虑业务主键的性能需求,可以把业务主键建立聚集索引,而逻辑主键只建立主键约束和非聚集索引即可。\r\n\r\n8、关系表可以考虑采用复合主键方式,复合主键不用于实体表。\r\n\r\n \r\n\r\n参考文献:\r\n\r\n关系数据库主键分析\r\nHibernate开发与实战\r\n数据库主键设计之思考\r\n[讨论]业务主键 Vs. 逻辑主键,到底哪个好?\r\n逻辑主键和联合主键,一定要讨论清楚!\r\n关于在表中设主键的问题\r\n关于在表中设主键的问题\r\n\r\n
\r\n ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2953, 'c-error-error-c2731-winmain-cannot-overload-function-2', 'C++ 错误提示error C2731:“WinMain”: 无法重载函数', '2012-04-28 23:01:51', '2019-03-25 21:29:22', '
\r\n错误代码:\r\nint WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow )
\r\n
\r\n

\r\n 照抄下来,在VS2008或VS2010编译的时候总会说error C2731: “WinMain”: 无法重载函数。

\r\n

\r\n 其实因为WinMain函数的原始定义中lpCmdLine的类型是char *,但在中文系统的环境下因为启用了Unicode支持,LPTSTR代表的是WCHAR *。所以上述函数我们就应该这样来写:

\r\n
\r\n
\r\n
\r\n修改后代码:
\r\n int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow )
\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2954, 'detailed-explanation-of-indexers-in-c-2', 'C#中索引器详解', '2012-04-28 06:01:16', '2019-03-25 21:29:22', '
\r\n 索引器概述 \r\n

\r\n 索引器使得对象可按照与数组相似的方法进行索引。

\r\n

\r\n get 访问器返回值。set 访问器分配值。

\r\n

\r\n this 关键字用于定义索引器。

\r\n

\r\n value 关键字用于定义由 set 索引器分配的值。

\r\n

\r\n 索引器不必根据整数值进行索引,由您决定如何定义特定的查找机制。

\r\n

\r\n 索引器可被重载。

\r\n

\r\n 索引器可以有多个形参,例如当访问二维数组时。

\r\n

\r\n C#语言一个最令人感兴趣的地 方就是类的索引器(indexer)。简单说来,所谓索引器就是一类特殊的属性,通过它们你就可以像引用数组一样引用 自己的类。显然,这一功能在创建集合类的场合特别有用,而在其他某些情况下,比如处理大型文件或者抽象某些有限资源等,能让类具有类似数组的行为当然也是 非常有用的。本文就会引领你设置类来采用索引器。但是,首先让我们概述下属性这个概念以便了解些必要的背景知识。

\r\n

\r\n 属性

\r\n

\r\n   假如你曾经用VB6编写过 程序,那么你应该很熟悉属性方法才对,所谓属性方法其实就是特殊的类成员,它实现了对私有类域的受控访问。在C#语言 中有两种属性方法,其一是get,通过它可以返回私有域的值,其二是set,通过它就可以设置私有域的值。比如说,以下面的代码为例,其间创建了一个 FirstName属性,由它控制对私有类成员firstname的访问:

\r\n

\r\n class Person {
\r\n private string firstname;
\r\n public string FirstName {
\r\n get {return firstname;}
\r\n set {firstname = value;}
\r\n }
\r\n }

\r\n

\r\n 属性声明可以如下编码:
\r\n Person p = new Person();
\r\n p.FirstName = "Lamont";
\r\n Console.WriteLine (p.FirstName); 

\r\n

\r\n   如你你所看到的那样,属性 声明倒更像是域声明,只不过它还声明了两个特殊的成员,按照微软的说法就是所谓的访问函数(accessor)。当某 一表达式的右边调用属性或者属性用作其他子程序(或者函数)的参数时即会调用get访问函数。反之,当表达式左边调用属性并且通过隐式传递value参数 设置私有域值的情况下就会调用set访问函数。你可以创建只读属性,方法是省略set访问函数,这样任何设置属性的尝试都会产生编译错误。

\r\n

\r\n 采用索引器的益处

\r\n

\r\n   说了半天咱们转到正题上来,那么为什么我要兜这个圈子呢?其实,这是因为类的索引器非常像属性,从代码上看也是这样。以下是具有索引器的类示例,通过索引器会返回一个字符串:

\r\n

\r\n class Sample {
\r\n public string this [int index] {
\r\n get {return "You passed " + index; }
\r\n }
\r\n } 

\r\n

\r\n   注意,这里的属性名是 this,意思是回引类的当前实例,参数列表包含在方括号而非括号之内。还有,这是一个只读索引器。为了把它改成读/写类 型,我又添加了一个get访问函数。在定义索引器的时候,你不一定只采用一个参数。索引器参数可以采用任何类型,不过int是通常采用也是最为合理的类 型。同一类中还可能拥有一个以上的索引器(重载)。

\r\n

\r\n   如上定义了Sample类之后,我们就可以把索引器用作某种默认的属性,如下所示:

\r\n

\r\n Sample s = new Sample();
\r\n Console.WriteLine(s[55]); 

\r\n

\r\n 属性和索引器

\r\n

\r\n    属性和索引器之间有好些差别:

\r\n

\r\n   类的每一个属性都必须拥有唯一的名称,而类里定义的每一个索引器都必须拥有唯一的签名(signature)或者参数列表(这样就可以实现索引器重载)。

\r\n

\r\n    属性可以是static(静态的)而索引器则必须是实例成员。

\r\n

\r\n   为索引器定义的访问函数可以访问传递给索引器的参数,而属性访问函数则没有参数。

\r\n

\r\n 接口

\r\n

\r\n   类似数组的行为常受到程序实现者的喜爱,所以你还可以为接口定义索引器,IList和 IDictionary集合接口都声明了索引器以便访问其存储的项目。

\r\n

\r\n   在为接口声明索引器的时候,记住声明只是表示索引器的存在。你只需要提供恰当的访问函数即可,不必包括范围修饰符。以下代码把索引器声明为接口IImplementMe的一部分:

\r\n

\r\n interface IImplementMe {
\r\n string this[int index]
\r\n {
\r\n get;
\r\n set;
\r\n } 

\r\n

\r\n   相应实现的类则必须为IimplementMe的索引器具体定义get和set访问函数。

\r\n

\r\n   以上就是有关索引器的一些基本概述了。现在你应该对索引器在你的开发中所具有的作用有了较深入的了解。

\r\n

\r\n 索引器允许类或结构的实例按照与数组相同的方式进行索引。索引器类似于属性,不同之处在于它们的访问器采用参数。

\r\n

\r\n 在下面的示例中,定义了一个泛型类,并为其提供了简单的 get 和 set 访问器方法(作为分配和检索值的方法)。Program 类为存储字符串创建了此类的一个实例。

\r\n

\r\n class SampleCollection<T>
\r\n {
\r\n     private T[] arr = new T[100];
\r\n     public T this[int i]
\r\n     {
\r\n         get
\r\n         {
\r\n             return arr[i];
\r\n         }
\r\n         set
\r\n         {
\r\n             arr[i] = value;
\r\n         }
\r\n     }
\r\n }

\r\n

\r\n // This class shows how client code uses the indexer
\r\n class Program
\r\n {
\r\n     static void Main(string[] args)
\r\n     {
\r\n         SampleCollection<string> stringCollection = new SampleCollection<string>();
\r\n         stringCollection[0] = "Hello, World";
\r\n         System.Console.WriteLine(stringCollection[0]);
\r\n     }
\r\n }

\r\n
\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2956, 'the-importance-of-data-structure-in-computer-science', '数据结构在计算机领域的重要性', '2012-04-26 06:04:00', '2019-03-25 21:29:22', '      数据结构在计算机科学中是一门综合性的专业基础课。在计算机科学中,数据结构不仅是一般程序设计的基础,而且是设计和编译程序、操作系统、数据库系统及其它系统程序和大型应用程序的重要基础。
\r\n      《数据结构》是一门计算机专业技术基础课,可作为《编译原理》《操作系统》、《数据库》、《信息检索》与《人工智能》等课程的基础,这门课程学习的效果将 直接影响到后续课程的学习;在学习和教学过程中,大多数初学者普遍反映这门课程比较抽象,理解起来有一定的难度。再加上计算机专业的发展,多媒体课件库资源的匮乏,编制相应课程的网络多媒体课件成为迫在眉睫的事情。
\r\n      计算机科学各领域及有关的应用软件都要用到各种数据结构。语言编译要使用栈、散列表及语法树;操作系统中用列、存储管理表及目录树等;数据库系统运用线性表、多链表及索引树等进行数据管理;而在人工智能领域,依求解问题性质的差异将涉及到各种不同的数据结构,如广义表、集合、搜索树及各种有向图等等. 数据结构目的是介绍一些最常用的数据结构,阐明数据结构内在的逻辑关系,讨论它们在计算机中的存储表示,并结合各种典型应用说明它们在进行各种运算(操 作)时的动产性质及实际的执行算法.进一步提高软件设计和编程水平. 通过对不同存储结构和相应算法的对比,增强我们求解问题性质选择合理的数据结构并控制求解算法的空间、时间及复杂性的能力。
\r\n      本栏目详细介绍了线性表、栈和队列、串、数组和广义表、树和二叉树及图等几种基本类型的数据结构,以及在程序设计中经常遇到的两个问题--查找和排序。

\r\n
\r\n栏目特色
\r\n   本栏目以MyEclipse,NetBeans,VS,VC++等软件为工具,对一些主要算法用C语言或类C语言或Java进行描述,使您更易理解掌握。在本栏目中,加入了大量习题和习题解答,使访问者可有效地学习和复习,并加入了一些实验内容,对数据结构的实习有所帮助。
\r\n

\r\n 栏目宗旨
\r\n 众所周知,任何实际问题只有建立了数学模型才可以被计算机计算,而数据结构就是实际问题中元素的数学抽象,算法则是建立和解决数学模型的方法,因此程序设计的核心问题算法和数据结构

\r\n       纵观目前国内的编程站点,大部分是关于VC,VB, Delphi,Java, HTML等编程语言,几乎没有研究讨论算法和数据结构的站点。这给程序设计的初学者造成了一个误区,认为学会某种编程语言或开发工具就是会编程了。其实计算机语言和开发工具只是编程的工具,掌握工具固然重要,但更重要的是掌握方法!而且,开发工具会不断地更新,新的计算机语言会不断地出现,今天学会的东西可能明天就会过时;但基本的算法却不会有太大改变。掌握了程序设计的算法,无论再学习何种语言和开发工具都可以很快地上手。
\r\n       本栏目应运而生,旨在帮助大家学习算法和数据结构,提高大家的编程水平,并提供一个讨论算法和数据结构的场所。如果您是计算机编程的初学者,本栏目可以帮助您 了解和学习算法和数据结构;如果您是高手,您可以在本站的高级专题中找到您感兴趣的课题;如果您是参加计算机竞赛的选手,那您来对了,本站提供了各类计算 机竞赛的题目和解析,以及一个丰富的题库,您将会发现本站会对您有很大的帮助。本站的内容覆盖面很广,从最基本的排序算法到最前沿的人工智能、遗传算法均 有所涉及,在这里您一定会找到适合您的内容。 请记住本栏目的宗旨:

\r\n

\r\n 程序=算法+数据结构

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2957, 'detailed-explanation-of-asp-in-the-on-error-resume-next', 'ASP中On Error Resume Next详解', '2012-04-24 06:38:53', '2019-03-25 21:29:22', 'On Error Resume Next
\r\nOn Error GoTo 0
\r\n说明:
\r\n如果在您的代码中未使用 On Error Resume Next 语句, 所发生的运行时错误将显示错误信息,同时,代码的执行也随之终止。但是运行代码的主机决定了具体操作。主机有时可有选择地处理各类错误。在有些情况下,它可以在出错的地方激活脚本调试器。而在另一些情况下,由于主机无法通知用户,因此对所发生的错误没有明确说明。至于如何处理错误则完全取决于主机的功能。
\r\n
\r\n在任意一个特殊过程中,只要在调用堆栈的地方启用错误处理程序,所发生的错误一般不会是致命性的。如果在一个过程中没有启用局部错误处理程序,当发生错误 时,控制可通过堆栈调用转移,直到找到一个具有错误处理程序的过程,并在出错的地方处理错误。如果在调用堆栈的过程中没有找到错误处理程序,则在出错的地 方显示错误信息,同时终止代码执行,或者通过主机来正确处理错误。
\r\n
\r\nOn Error Resume Next 会使程序按照产生错误的语句之后的语句继续执行,或是按照最近一次所调用的过程(该过程含有 On Error Resume Next 语句)中的语句继续运行。这个语句可以不顾运行时错误,继续执行程序,之后您可以在过程内部建立错误处理例程。在调用另一个过程时,On Error Resume Next 语句变为非活动的。所以,如果希望在例程中进行内部错误处理,则应在每一个调用的例程中执行 On Error Resume Next 语句。
\r\n
\r\n当调用另一过程时,禁止使用On Error Resume Next 语句,因此如果您想在例程中嵌入错误处理程序,则需要在每次调用例程时都应执行 On Error Resume Next 语句。当退出一个过程时,错误处理程序可恢复到它在进入所退出过程之前的状态。
\r\n
\r\n如果您已启用 On Error Resume Next 错误处理程序,则可使用 On Error GoTo 0禁用错误处理程序。
\r\n
\r\n下面例子举例说明如何使用 On Error Resume Next 语句:
\r\n
\r\nOn Error Resume Next
\r\nErr.Raise 6 ' 引发溢出错误。
\r\nMsgBox ("Error # " & CStr(Err.Number) & " " & Err.Description)
\r\nErr.Clear '清除该错误。    
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2958, '3-java-applets-bisection-lookup', '二分法查找', '2012-04-23 00:28:05', '2019-03-25 21:29:22', '
\r\n
\r\n

\r\n public class BinarySearch// 二分查找,注意:二分查找只是针对有序排列的各种数组或集合

\r\n

\r\n {

\r\n

\r\n     static int binarySearch(int target, int[] array)

\r\n

\r\n     {

\r\n

\r\n         int front = 0;

\r\n

\r\n         int tail = array.length - 1;

\r\n

\r\n         // 判断子数组是否能再次二分

\r\n

\r\n         while (front <= tail)

\r\n

\r\n         {

\r\n

\r\n             // 获取子数组的中间位置,并依据此中间位置进行二分

\r\n

\r\n             int middle = (front + tail) / 2;

\r\n

\r\n  

\r\n

\r\n             if (array[middle] == target)

\r\n

\r\n             {

\r\n

\r\n                 return middle + 1;

\r\n

\r\n             }

\r\n

\r\n             else if (array[middle] > target)

\r\n

\r\n             {

\r\n

\r\n                 tail = middle - 1;

\r\n

\r\n             }

\r\n

\r\n             else

\r\n

\r\n             {

\r\n

\r\n                 front = middle + 1;

\r\n

\r\n             }

\r\n

\r\n         }

\r\n

\r\n         return -1;

\r\n

\r\n     }

\r\n

\r\n  

\r\n

\r\n     public static void main(String[] args)

\r\n

\r\n     {

\r\n

\r\n         int[] array = new int[] { 1, 2, 3, 5, 7, 9, 17, 21, 45 };

\r\n

\r\n         System.out.println(binarySearch(45, array));

\r\n

\r\n     }

\r\n

\r\n }

\r\n

\r\n  

\r\n
\r\n
\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2959, 'wincvs-ccvsno-logon-appear-in-such-repository-solutions-2', 'WinCvs里登录出现C:/cvs: no such repository解决方案', '2012-04-22 04:37:09', '2019-03-25 21:29:22', '1 、下载cvsNt地址\r\nhttp://www.march-hare.com/cvsnt/features/cvsnt/\r\n2、创建仓库(Ropository)                          (版本为:CVS 2.5.03)\r\n安装完成后,打开 \"开始\"菜单——>“程序”——> “CVSNT\"——> \"CVSNT Control Panel\" 程序 ,打开cvs管\r\n理窗品,选择\"Ropository configuation\"选项卡,单击\"add\"按钮添加仓库,location为文件本机存放路径。\r\n选择一个路径。Name会自动改为\"/目录文件夹\"! 这个名子也可以修改。点击OK按钮,它会提示你“这个\r\n文件夹不是cvs仓库,是否初始化?”的英文提示。点击“是“。创建仓库完毕。如下图\r\n\r\n       \"查看更多精彩图片\"\r\n\r\n3、创建新用户\r\ncvs默认高级管理员为windows高级管理员。在添加新用户时,首先用高级管理员登陆。步骤如下:\r\n1> 打开Dos窗口 输入以一命令\r\nset cvsroot=:pserver:administrator@127.0.0.1:/cvs    回车\r\n其中“/cvs”就是在创建仓库时的name\r\n\r\n                 如下图\r\n\r\n                \"查看更多精彩图片\"\r\n2>输入cvs login                              回车\r\n3>输入administrator的密码                回车\r\n4>输入cvs passwd -a xgz //添加用户xgz    回车\r\n5>输入新密码\r\n6>再次输入密码\r\n\r\n                  如下图\r\n\"查看更多精彩图片\"\r\n\r\nOK新用户创建成功!\r\n\r\nset cvsroot=:pserver:xgz@127.0.0.1:/cvsRoot   测试一下\r\n\r\n别忘了 cvs login\r\n\r\n输入密码登陆测试添加用户是否成功.\r\n\r\n                  \"查看更多精彩图片\"   \r\n\r\n如果出现\r\n\r\nFatal error, aborting.\r\ncvs [login aborted]: test1: no such user\r\n\r\n这种错误.还要打开\"CVSNT Control Panel\" 程序在\"Server Settings\"选项卡的Run as 下拉框,选中administrator   默认为 client user\r\n\r\n \r\n\r\n     WinCVS配置\r\n\r\n      \"查看更多精彩图片\"\r\n\r\n      \"查看更多精彩图片\"\r\n=================================================================================\r\n\r\n相关问题\r\n\r\n解决新版本CVSNT中“no such repository”问题。    \r\n\r\n----------------------------------------------------------------------------------------\r\n\r\n       以前安装过cvsnt一直可以使用,不过前一段时间打算在自己的计算机安装以下cvsnt,那里客户端登陆时候一直提示“no such repository”,可是明明我的repository已经建立。可是还不成功。一直以为是系统问题,今天无意之间修改了设置,那里知道竟然可以登 陆,创建模块和check out。仔细看了一下原来是设置有一个问题,最新的cvsnt可能采用unix的设置访问方式,即使你是cvsnt也不需要些盘符。\r\n\r\n原来设置:\r\n\r\n------------------------------------------------------\r\n\r\ncvs -d :pserver:txshi@127.0.0.1:d:/cvs login\r\nLogging in to :pserver:txshi@127.0.0.1:2401:d:/cvs\r\ncvs [login aborted]: d:/cvs: no such repository\r\n\r\n***** CVS exited normally with code 1 *****\r\n\r\n------------------------------------------------------\r\n\r\n现在设置\r\n\r\n------------------------------------------------------\r\n\r\ncvs -d :pserver:txshi@127.0.0.1:2401:/cvs login\r\nLogging in to :pserver:txshi@127.0.0.1:2401:/cvs\r\n\r\n***** CVS exited normally with code 0 *****\r\n------------------------------------------------------\r\n\r\n看到网络上好多人遇到和我一样的问题,苦苦不能解决。希望大家能解此问题。\r\n\r\n ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2960, 'java-stringbuffer-in-detail-2', 'Java中的StringBuffer详解', '2012-04-20 00:18:32', '2019-03-25 21:29:22', '      要知道StringBuffer的用法,必须知道他和String之间的关系,因为你都在StringBuffer了,必然是碰到了String不能解决的问题。\r\n 1、构造函数。\r\nStringBuffer() :构造一个没有任何字符的StringBuffer类。\r\nStringBuffer(int length) : :构造一个没有任何字符的StringBuffer类,并且,其长度为length。\r\nStringBuffer(String str) :以str为初始值构造一个StringBuffer类。\r\n 2、方法。\r\n说明:\r\n所有方法均为public;\r\n书写格式:〔修饰符〕   <返回类型> <方法名(〔参数列表〕)>\r\n如:\r\nstatic int parseInt(String s) 表示:此方法(parseInt)为类方法(static),返回类型为(int),方法所需参数为String类型。\r\n\r\n1. StringBuffer append(boolean b)\r\n2. StringBuffer append(char c)\r\n3. StringBuffer append(char[] str)\r\n4. StringBuffer append(char[] str, int offset, int len)\r\n5. StringBuffer append(double d)\r\n6. StringBuffer append(float f)\r\n7. StringBuffer append(int i)\r\n8. StringBuffer append(long l)\r\n9. StringBuffer append(Object obj)\r\n10. StringBuffer append(String str)\r\n11. StringBuffer append(StringBuffer sb)\r\n以上的方法都是向字符串缓冲区“追加”元素,但是,这个“元素”参数可以是布尔量、字符、字符数组、双精度数、浮点数、整型数、长整型数对象类型的字符串、字符串和StringBuffer类等。如果添加的字符超出了字符串缓冲区的长度,Java将自动进行扩充。\r\n\r\nString question = new String(\"1+1=\");\r\nint answer = 3;\r\nboolean result = (1+1==3);\r\nStringBuffer sb = new StringBuffer();\r\nsb.append(question);\r\nsb.append(answer);\r\nsb.append(‘t‘);\r\nsb.append(result);\r\nSystem.out.println(sb);\r\n结果为:1+1=3    false\r\n\r\n12. int capacity() :返回当前StringBuffer对象(字符串缓冲区)的总空间,而非字符号串的长度。\r\n13. char charAt(int index) :在当前StringBuffer对象中取索引号为index的字符。第一个字符的索引为“0”\r\n14. StringBuffer delete(int start, int end) :删除当前StringBuffer对象中以索引号start开始,到end结束的子串。\r\n15. StringBuffer deleteCharAt(int index) :删除当前StringBuffer对象中索引号为index的字符。\r\n16. void ensureCapacity(int minimumCapacity) :重新设置字符号串缓冲区的总空间。如果minimumCapacity大于当前的总空间,则新的空间被设置:一种结果是minimumCapacity;另一种结果是{“老空间”乘2加2}。\r\n\r\nStringBuffer sb1 = new StringBuffer(5);\r\nStringBuffer sb2 = new StringBuffer(5);\r\nsb1.ensureCapacity(6);\r\nsb2.ensureCapacity(100);\r\nSystem.out.println( \"sb1.Capacity: \" + sb1.capacity() );\r\nSystem.out.println( \"sb2.Capacity: \" + sb2.capacity() );\r\n结果为:sb1.Capacity: 12sb2.Capacity: 100\r\n\r\n17. void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) :从当前StringBuffer对象的索引号srcBegin开始,到srcEnd结束的子串,赋值到字符数组dst中,并且从dst的索引号dstBegin开始。\r\n\r\nStringBuffer sb = new StringBuffer(\"I love her!\");\r\nchar[] i = {‘I‘,‘ ‘,‘l‘,‘o‘,‘v‘,‘e‘,‘ ‘,‘y‘,‘o‘,‘u‘};\r\nsb.getChars(7,10,i,7);\r\nSystem.out.println( \"sb: \" + sb );\r\n结果为:sb: I love her!\r\n\r\n18. int indexOf(String str) :返回当前StringBuffer对象中,第一个满足str子串的位置。\r\n19. int indexOf(String str, int fromIndex) :从当前StringBuffer对象的fromIndex开始查找,返回第一个满足str子串的位置。\r\n20. StringBuffer insert(int offset, boolean b)\r\n21. StringBuffer insert(int offset, char c)\r\n22. StringBuffer insert(int offset, char[] str)\r\n23. StringBuffer insert(int index, char[] str, int offset, int len)\r\n24. StringBuffer insert(int offset, double d)\r\n25. StringBuffer insert(int offset, float f)\r\n26. StringBuffer insert(int offset, int i)\r\n27. StringBuffer insert(int offset, long l)\r\n28. StringBuffer insert(int offset, Object obj)\r\n29. StringBuffer insert(int offset, String str)\r\n\r\n以上的方法都是在当前StringBuffer对象中插入一个元素,在索引号offset处插入相应的值。\r\n30. int lastIndexOf(String str) :返回当前StringBuffer对象中,最后一个满足str子串的位置。\r\n31. int lastIndexOf(String str, int fromIndex) :从当前StringBuffer对象的fromIndex开始查找,返回最后一个满足str子串的位置。\r\n32. int length() :返回当前StringBuffer对象(字符缓冲区)中,字符串的长度。注意:此方法与capacity() 不同。\r\n33. StringBuffer replace(int start, int end, String str) :替换当前StringBuffer对象的字符串。从start开始,到end结束的位置替换成str。\r\n34. StringBuffer reverse() :将字符串翻转。\r\n\r\nStringBuffer sb = new StringBuffer(\"0123456789\");\r\nSystem.out.println( \"sb.reverse(): \" + sb.reverse() );\r\n结果为:sb.reverse(): 9876543210\r\n\r\n35. void setCharAt(int index, char ch) :设置索引号index的字符为ch。\r\n36. void setLength(int newLength) :重新设置字符串缓冲区中字符串的长度,如果newLength小于当前的字符串长度,将截去多余的字符。\r\n\r\nStringBuffer sb = new StringBuffer(\"0123456789\");\r\nsb.setLength(5);\r\nSystem.out.println( \"sb: \" + sb );\r\n结果为:sb: 01234\r\n\r\n37. String substring(int start) :取当前StringBuffer对象中,从start开始到结尾的子串。\r\n38. String substring(int start, int end) :取当前StringBuffer对象中,从start开始到end的子串。\r\n39. String toString() :将当前StringBuffer对象转换成String对象。\r\n\r\nString和StringBuffer的区别\r\n网上资料可以说是数不胜数,但是看到这篇文章,感觉里面做的小例子很有代表性,所以转一下,并自己做了一点总结。\r\n 1.两者的区别 \r\n在java中有3个类来负责字符的操作。\r\n1.Character 是进行单个字符操作的,\r\n2.String 对一串字符进行操作。不可变类。\r\n3.StringBuffer 也是对一串字符进行操作,但是可变类。\r\nString:\r\n是对象不是原始类型. \r\n为不可变对象,一旦被创建,就不能修改它的值.\r\n对于已经存在的String对象的修改都是重新创建一个新的对象,然后把新的值保存进去.\r\nString 是final类,即不能被继承.\r\nStringBuffer:\r\n是一个可变对象,当对他进行修改的时候不会像String那样重新建立对象\r\n它只能通过构造函数来建立,\r\nStringBuffer sb = new StringBuffer();\r\nnote:不能通过付值符号对他进行付值.\r\nsb = \"welcome to here!\";//error\r\n对象被建立以后,在内存中就会分配内存空间,并初始保存一个null.向StringBuffer\r\n中付值的时候可以通过它的append方法.\r\nsb.append(\"hello\");\r\n字符串连接操作中StringBuffer的效率要比String高:\r\nString str = new String(\"welcome to \");\r\nstr += \"here\";\r\n的处理步骤实际上是通过建立一个StringBuffer,然后调用append(),最后\r\n再将StringBuffer toSting();\r\n这样的话String的连接操作就比StringBuffer多出了一些附加操作,当然效率上要打折扣.\r\n并且由于String 对象是不可变对象,每次操作Sting 都会重新建立新的对象来保存新的值.\r\n这样原来的对象就没用了,就要被垃圾回收.这也是要影响性能的.\r\n看看以下代码:\r\n将26个英文字母重复加了5000次,\r\n  String tempstr = \"abcdefghijklmnopqrstuvwxyz\";\r\nint times = 5000;\r\nlong lstart1 = System.currentTimeMillis();\r\nString str = \"\";\r\nfor (int i = 0; i < times; i++) {\r\nstr += tempstr;\r\n}\r\nlong lend1 = System.currentTimeMillis();\r\nlong time = (lend1 - lstart1);\r\nSystem.out.println(time); \r\n可惜我的计算机不是超级计算机,得到的结果每次不一定一样一般为 46687左右。\r\n也就是46秒。\r\n我们再看看以下代码\r\n         String tempstr = \"abcdefghijklmnopqrstuvwxyz\";\r\nint times = 5000;\r\nlong lstart2 = System.currentTimeMillis();\r\nStringBuffer sb = new StringBuffer();\r\nfor (int i = 0; i < times; i++) {\r\nsb.append(tempstr);\r\n}\r\nlong lend2 = System.currentTimeMillis();\r\nlong time2 = (lend2 - lstart2);\r\nSystem.out.println(time2); \r\n得到的结果为 16 有时还是 0 所以结论很明显,StringBuffer 的速度几乎是String 上万倍。当然这个数据不是很准确。因为循环的次数在100000次的时候,差异更大。不信你试试。\r\n\r\n根据上面所说:\r\nstr += \"here\";\r\n的处理步骤实际上是通过建立一个StringBuffer,调用append(),最后\r\n再将StringBuffer toSting();\r\n所以str += \"here\";可以等同于\r\nStringBuffer sb = new StringBuffer(str);\r\nsb.append(\"here\");\r\nstr = sb.toString();\r\n所以上面直接利用\"+\"来连接String的代码可以基本等同于以下代码\r\n String tempstr = \"abcdefghijklmnopqrstuvwxyz\";\r\nint times = 5000;\r\nlong lstart2 = System.currentTimeMillis();\r\nString str = \"\";\r\nfor (int i = 0; i < times; i++) {\r\nStringBuffer sb = new StringBuffer(str);\r\nsb.append(tempstr);\r\nstr = sb.toString();\r\n}\r\nlong lend2 = System.currentTimeMillis();\r\nlong time2 = (lend2 - lstart2);\r\nSystem.out.println(time2); \r\n平均执行时间为46922左右,也就是46秒。\r\n2 StringBuffer可变String不可变的真正原因 \r\nString和StringBuffer都是final类,他们生成的对象在堆中都是不可变的,在他们内部都是靠属性char数组实现的, \r\n那为什么StringBuffer可以在对象中追加字符串呢?呵呵,因为String中的char数组是finall的,也就是常量,是不可改变的,而StringBuffer继承自抽象类AbstractStringBuilder,他的内部实现靠他的父类完成,AbstractStringBuilder内的char数组是变量,可以用append追加 StringBuffer和StringBuilder都实现了AbstractStringBuilder抽象类,此抽象类实现Appendable接口因此可追加 (在JDK 6.0 API中StringBuilder和Stringbuff写着都继承自Object 而且在他的API中找不到AbstractStringBuilder类)\r\n3 到底该怎么简洁的回答 \r\nStringBuffer 支持多线程,也就是说StringBuffer是线程安全的。在连接字符串时直接用:Append(\"string\")就行,它的容量比较大,可以包含整篇文章。\r\nString不支持线程,所以它不安全,虽然在连接字符串时可用\"+\",但需要注意的是每\"+\"一次的同时就会在内存(堆)中增加一个空间地址。相对而言,你加的多了,就会使JVM出现内存溢出等错误。\r\n\r\n如果在面试的时候出现这种题:你直接说:StringBuffer是线程安全的,String 则不是。就行了。\r\n总结: 如果在程序中需要对字符串进行频繁的修改连接操作的话.使用StringBuffer性能会更高。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2961, 'design-of-quadrilateral-base-class-cquadrangle-4-redesigning-derived-classes-namely-calculation-of-rectangular-square-area-perimeter-and-diagonal-length-calculate-the-area-of-a-trapezoid-and-par', '设计四边形基类CQuadrangle,再设计4个派生类,分别计算长方形、正方形的面积、周长及对角线长。计算平行四边形及梯形的面积。', '2012-04-19 06:48:40', '2019-03-25 21:29:22', '源码:\r\n
#include <math.h>
\r\n#include <iostream>
\r\nusing namespace std;
\r\n
\r\nclass CQuadrangle//四边形类
\r\n{
\r\npublic:
\r\n    CQuadrangle(int ed)//构造函数
\r\n    {
\r\n        edge=ed;
\r\n    }
\r\n    ~CQuadrangle(){}//析构函数
\r\n
\r\n    int area()//求面积
\r\n    {
\r\n        return 0;
\r\n    }
\r\n
\r\n    int  Perimeter()//求周长
\r\n    {
\r\n        return 0;
\r\n    }
\r\n    int DiagonalLength()//求对角线长
\r\n    {
\r\n        return 0;
\r\n    }
\r\n
\r\nprotected://成员变量
\r\n    int edge;
\r\n    int diagonal;
\r\n};
\r\n
\r\nclass Rectangle:public  CQuadrangle//派生长方形类
\r\n{
\r\npublic:
\r\n    Rectangle(int le,int wi):CQuadrangle(le)
\r\n    {
\r\n        length=le;
\r\n        width=wi;
\r\n    }
\r\n    ~Rectangle(){}
\r\n    int area() const
\r\n    {
\r\n        return length*width;
\r\n    }
\r\n    int  Perimeter()
\r\n    {
\r\n        return (width+length)*2;
\r\n    }
\r\n    float DiagonalLength()
\r\n    {
\r\n        return sqrt((float)(width*width+length*length));
\r\n    }
\r\n
\r\nprotected:
\r\n    int length;
\r\n    int width;
\r\n    int diagonal;
\r\n};
\r\n
\r\nclass Square:public  CQuadrangle//派生正方形类
\r\n{
\r\npublic:
\r\n    Square(int ed):CQuadrangle(ed)
\r\n    {
\r\n        edge=ed;
\r\n    }
\r\n    ~Square(){}
\r\n    int area() const
\r\n    {
\r\n        return edge*edge;
\r\n    }
\r\n    int  Perimeter()
\r\n    {
\r\n        return edge*4;
\r\n    }
\r\n    float DiagonalLength()
\r\n    {
\r\n        return sqrt(2.0)*edge;//注意,只能写2.0,不能写2,否则VS编译不通过
\r\n    }
\r\n
\r\nprotected:
\r\n    int edge;
\r\n    int diagonal;
\r\n};
\r\n
\r\nclass Parallelogram:public  CQuadrangle//派生平行四边形类
\r\n{
\r\npublic:
\r\n    Parallelogram(int to,int hi):CQuadrangle(to)
\r\n    {
\r\n        top=to;
\r\n        high=hi;
\r\n    }
\r\n    ~Parallelogram(){}
\r\n    int area() 
\r\n    {
\r\n        return top*high;
\r\n    }
\r\n
\r\nprotected:
\r\n    int top;
\r\n    int high;    
\r\n};
\r\n
\r\nclass Trapezoid:public  CQuadrangle//派生梯形类
\r\n{
\r\npublic:
\r\n    Trapezoid(int u,int dow,int hi):CQuadrangle(u)
\r\n    {
\r\n        up=u;
\r\n        down=dow;
\r\n        high=hi;
\r\n    }
\r\n    ~Trapezoid(){}
\r\n    int area() const
\r\n    {
\r\n        return ((up+down)*high)/2;
\r\n    }
\r\n
\r\nprotected:
\r\n    int up;
\r\n    int down;
\r\n    int high;    
\r\n};
\r\n
\r\n
\r\nint main()
\r\n{
\r\n    Rectangle rt(3,2);//长方形测试
\r\n    cout<<\"测试的长方形长为3,宽为2:\"<<endl;
\r\n    cout<<\"长方形的面积:\"<<rt.area()<<endl;
\r\n    cout<<\"长方形的周长:\"<<rt.Perimeter()<<endl;
\r\n    cout<<\"长方形的对角线长:\"<<rt.DiagonalLength()<<endl;
\r\n    cout<<endl;
\r\n    cout<<\"测试的正方形边长为2:\"<<endl;
\r\n    Square sq(2);//正方形测试
\r\n    cout<<\"正方形的面积:\"<<sq.area()<<endl;
\r\n    cout<<\"正方形的周长:\"<<sq.Perimeter()<<endl;
\r\n    cout<<\"正方形的对角线长:\"<<sq.DiagonalLength()<<endl;
\r\n    cout<<endl;
\r\n    cout<<\"测试的平行四边形底为2,高为3:\"<<endl;
\r\n    Parallelogram pa(2,3);//平行四边形测试
\r\n    cout<<\"平行四边形的面积:\"<<pa.area()<<endl;
\r\n    cout<<endl;
\r\n    cout<<\"测试的梯形上底为2,下底为3,高为4:\"<<endl;
\r\n    Trapezoid tp(2,3,4);//梯形测试
\r\n    cout<<\"梯形的面积:\"<<tp.area()<<endl;
\r\n    return 0;
\r\n}
\r\n演示:\r\n\"\"', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2962, 'detailed-explanation-of-the-string-classes-in-the-java-2', 'Java中的String类详解', '2012-04-17 06:43:53', '2019-03-25 21:29:22', '      Java字符串类(java.lang.String)是Java中使用最多的类,也是最为特殊的一个类,很多时候,我们对它既熟悉又陌生。
\r\n  一、从根本上认识java.lang.String类和String池
\r\n  首先,我建议先看看String类的源码实现,这是从本质上认识String类的根本出发点。从中可以看到:
\r\n  1、String类是final的,不可被继承。public final class String。
\r\n  2、String类是的本质是字符数组char[], 并且其值不可改变。private final charvalue[];
\r\n  然后打开String类的API文档,可以发现:
\r\n  3、String类对象有个特殊的创建的方式,就是直接指定比如String x =\"abc\",\"abc\"就表示一个字符串对象。而x是\"abc\"对象的地址,也叫做\"abc\"对象的引用。
\r\n  4、String对象可以通过“+”串联。串联后会生成新的字符串。也可以通过concat()来串联,这个后面会讲述。
\r\n  6、Java运行时会维护一个String Pool(String池),JavaDoc翻译很模糊“字符串缓冲区”。String池用来存放运行时中产生的各种字符串,
\r\n  并且池中的字符串的内容不重复。而一般对象不存在这个缓冲池,并且创建的对象仅仅存在于方法的堆栈区。
\r\n  5、创建字符串的方式很多,归纳起来有三类:
\r\n  其一,使用new关键字创建字符串,比如String s1 = new String(\"abc\");
\r\n  其二,直接指定。比如String s2 = \"abc\";
\r\n  其三,使用串联生成新的字符串。比如String s3 = \"ab\" + \"c\"; 
\r\n  二、String对象的创建
\r\n  String对象的创建也很讲究,关键是要明白其原理。
\r\n  原理1:当使用任何方式来创建一个字符串对象s时,Java运行时(运行中JVM)会拿着这个X在String池中找是否存在内容相同的字符串对象,如果不存在,则在池中创建一个字符串s,否则,不在池中添加。
\r\n  原理2:Java中,只要使用new关键字来创建对象,则一定会(在堆区或栈区)创建一个新的对象。
\r\n  原理3:使用直接指定或者使用纯字符串串联来创建String对象,则仅仅会检查维护String池中的字符串,池中没有就在池中创建一个,有则罢了!但绝不会在堆栈区再去创建该String对象。
\r\n  原理4:使用包含变量的表达式来创建String对象,则不仅会检查维护String池,而且还会在堆栈区创建一个String对象。
\r\n  另外,String的intern()方法是一个本地方法,定义为public native String intern(); intern()方法的价值在于让开发者能将注意力集中到String池上。当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(该对象由 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并且返回此 String 对象的引用。
\r\n  三、不可变类
\r\n  不可改变的字符串具有一个很大的优点:编译器可以把字符串设置为共享。 
\r\n  不可变类String有一个重要的优点-它们不会被共享引用。
\r\n  是这样的,JAVA为了提高效率,所以对于String类型进行了特别的处理---为string类型提供了串池 
\r\n  定义一个string类型的变量有两种方式: 
\r\n  string name= \"tom \"; 
\r\n  string name =new string( \"tom \") 
\r\n  使用第一种方式的时候,就使用了串池, 
\r\n  使用第二中方式的时候,就是一种普通的声明对象的方式 
\r\n  如果你使用了第一种方式,那么当你在声明一个内容也是 \"tom \"的string时,它将使用串池里原来的那个内存,而不会重新分配内存,也就是说,string saname= \"tom \",将会指向同一块内存 
\r\n  另外关于string类型是不可改变的问题: 
\r\n  string类型是不可改变的,也就是说,当你想改变一个string对象的时候,比如name= \"madding \" 
\r\n  那么虚拟机不会改变原来的对象,而是生成一个新的string对象,然后让name去指向它,如果原来的那个 \"tom \"没有任何对象去引用它,虚拟机的垃圾回收机制将接收它。 
\r\n  据说这样可以提高效率!!!
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2963, 'detailed-explanation-of-out-and-ref-in-c-2', 'C#中ref和out详解', '2012-04-16 06:50:22', '2019-03-25 21:29:22', '  ref是传递参数的地址,out是返回值,两者有一定的相同之处,不过也有不同点。\r\n\r\n  - 使用ref前必须对变量赋值,out不用。\r\n\r\n  - out的函数会清空变量,即使变量已经赋值也不行,退出函数时所有out引用的变量都要赋值,ref引用的可以修改,也可以不修改。\r\n\r\n  区别可以参看下面的代码:\r\n\r\n\r\n\r\n\r\n\r\n\r\n
     using System;\r\nclass TestApp\r\n{\r\nstatic void outTest(out int x, out int y)\r\n{//离开这个函数前,必须对x和y赋值,否则会报错。\r\n//y = x;\r\n//上面这行会报错,因为使用了out后,x和y都清空了,需要重新赋值,即使调用函数前赋过值也不行\r\nx = 1;\r\ny = 2;\r\n}\r\nstatic void refTest(ref int x, ref int y)\r\n{\r\nx = 1;\r\ny = x;\r\n}\r\npublic static void Main()\r\n{\r\n//out test\r\nint a,b;\r\n//out使用前,变量可以不赋值\r\noutTest(out a, out b);\r\nConsole.WriteLine(\"a={0};b={1}\",a,b);\r\nint c=11,d=22;\r\noutTest(out c, out d);\r\nConsole.WriteLine(\"c={0};d={1}\",c,d);\r\n//ref test\r\nint m,n;\r\n//refTest(ref m, ref n);\r\n//上面这行会出错,ref使用前,变量必须赋值\r\nint o=11,p=22;\r\nrefTest(ref o, ref p);\r\nConsole.WriteLine(\"o={0};p={1}\",o,p);\r\n}\r\n}
\r\n\"\"\r\n详解:\r\n\r\n  ref和out的区别在C# 中,既可以通过值也可以通过引用传递参数。通过引用传递参数允许函数成员更改参数的值,并保持该更改。若要通过引用传递参数, 可使用ref或out关键字。ref和out这两个关键字都能够提供相似的功效,其作用也很像C中的指针变量。它们的区别是:\r\n\r\n  1、使用ref型参数时,传入的参数必须先被初始化。对out而言,必须在方法中对其完成初始化。\r\n\r\n  2、使用ref和out时,在方法的参数和执行方法时,都要加Ref或Out关键字。以满足匹配。\r\n\r\n  3、out适合用在需要retrun多个返回值的地方,而ref则用在需要被调用的方法修改调用者的引用的时候。\r\n\r\n  注:在C#中,方法的参数传递有四种类型:传值(by value)传址(by reference)输出参数(by output)数组参数(by array)传值参数无需额外的修饰符,传址参数需要修饰符ref,输出参数需要修饰符out,数组参数需要修饰符params。传值参数在方法调用过 程中如果改变了参数的值,那么传入方法的参数在方法调用完成以后并不因此而改变,而是保留原来传入时的值。传址参数恰恰相反,如果方法调用过程改变了参数 的值,那么传入方法的参数在调用完成以后也随之改变。实际上从名称上我们可以清楚地看出两者的含义--传值参数传递的是调用参数的一份拷贝,而传址参数传 递的是调用参数的内存地址,该参数在方法内外指向的是同一个存储位置。\r\n\r\n  方法参数上的 ref 方法参数关键字使方法引用传递到方法的同一个变量。当控制传递回调用方法时,在方法中对参数所做的任何更改都将反映在该变量中。\r\n\r\n  若要使用 ref 参数,必须将参数作为 ref 参数显式传递到方法。ref 参数的值被传递到 ref 参数。\r\n\r\n  传递到 ref 参数的参数必须最先初始化。将此方法与 out 参数相比,后者的参数在传递到 out 参数之前不必显式初始化。\r\n\r\n  属性不是变量,不能作为 ref 参数传递。\r\n\r\n  如果两种方法的声明仅在它们对 ref 的使用方面不同,则将出现重载。但是,无法定义仅在 ref 和 out 方面不同的重载。\r\n\r\n  方法参数上的 out 方法参数关键字使方法引用传递到方法的同一个变量。当控制传递回调用方法时,在方法中对参数所做的任何更改都将反映在该变量中。\r\n\r\n  当希望方法返回多个值时,声明 out 方法非常有用。使用 out 参数的方法仍然可以返回一个值。一个方法可以有一个以上的 out 参数。\r\n\r\n  若要使用 out 参数,必须将参数作为 out 参数显式传递到方法。out 参数的值不会传递到 out 参数。\r\n\r\n  不必初始化作为 out 参数传递的变量。然而,必须在方法返回之前为 out 参数赋值。\r\n\r\n  属性不是变量,不能作为 out 参数传递。\r\n\r\n  网上有很多文章说ref 只传值,out传地址等等这种说法,好像不是非常的准确。以下是我做的实例代码,大家可以去试试:\r\n\r\n\r\n\r\n\r\n\r\n\r\n
\r\n     using System;\r\nusing System.Windows.Forms;\r\npublic class Test\r\n{\r\npublic static void Main()\r\n{\r\ncmdOut_Click();\r\n}\r\npublic static int RefValue(int i, ref int j)\r\n{\r\nint k = j;\r\nj = 222;\r\nreturn i + k;\r\n}\r\npublic static int OutValue(int i, out int j)\r\n{\r\nj = 222;\r\nreturn i + j;\r\n}\r\nprivate static void cmdRef_Click()\r\n{\r\nint m = 0;\r\nMessageBox.Show(RefValue(1, ref m).ToString());\r\nMessageBox.Show(m.ToString());\r\n}\r\nprivate static void cmdOut_Click()\r\n{\r\nint m;\r\nMessageBox.Show(OutValue(1, out m).ToString());\r\nMessageBox.Show(m.ToString());\r\n}\r\n}
\r\n \r\n\r\n ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2965, 'display-return-in-detail-how-iis7-http500-error-message-2', 'IIS7如何显示、返回详细HTTP500错误信息', '2012-04-15 03:55:53', '2019-03-25 21:29:22', '
      通过 IIS 配置按住 WIN + R 打开命令行输入 inetmgr 打开 IIS 管理 左边目录选择目标站点,在右边 IIS 块中双击 错误页 在 错误页 中右边的 操作,选择 编辑功能设置 在 错误响应 中,选择 详细错误,单击 确定 完成配置。
\r\n
      通过命令行启用详细错误:
\r\n%windir%system32inetsrvappcmd.exe set config \"Default Web Site/yourapp\" /section:httpErrors /errorMode:Detailed\r\n\r\n禁用详细错误:\r\n\r\n%windir%system32inetsrvappcmd.exe set config \"Default Web Site/yourapp\" /section:httpErrors /errorMode:Custom\r\n
      通过 web.config 配置
\r\n其实,上面在两种配置,最终都会反应到对应的 web.config 中。因此,我们可以直接编辑 web.config。特别是对于买的虚拟主机(Shared Web Hosting),没有权限更改IIS。打开网站目录,找到 web.config 文件(如果没有,就建立一个 txt 文件存为 web.config),找到 system.webServer 配置节,添加配置 <httpErrors errorMode=\"DetailedLocalOnly\" />。\r\n
<configuration>\r\n<system.webServer>\r\n<httpErrors errorMode=\"DetailedLocalOnly\"/>\r\n</system.webServer>\r\n</configuration>
\r\n      注意\r\n      此参数选项可以应用到网站或子目录或虚拟目录。 此参数选项对所有 IIS 应用程序有效,包括 ASP, APS.NET, PHP 等。\r\n\r\n如果是 ASP.NET 程序,可能还需要配置 <customErrors mode=”Off” />\r\n<system.web>\r\n<customErrors mode=”Off” />\r\n</system.web>\r\n此外,如果是 ASP 程序,还可以配置 sendErrorsToBrowser 选项:\r\n      通过 IIS 配置按住 WIN + R 打开命令行输入 inetmgr 打开 IIS 管理 左边目录选择目标站点,在右边 IIS 块中双击 ASP 在 ASP 页中展开 调试属性 节点 找到 启用客户端调试,选择 true 右边 操作中,单击 应用\r\n
      通过命令行启用:
\r\n%windir%system32inetsrvappcmd set config -section:asp -scriptErrorSentToBrowser:true\r\n\r\n禁用:\r\n\r\n%windir%system32inetsrvappcmd set config -section:asp -scriptErrorSentToBrowser:false\r\n\r\n注意上面参数中 config 后面不能指定站点目录。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2966, 'iis-error-solution-v-the-microsoft-jet-database-engine-error-80040e09-cannot-be-updated-database-or-object-is-read-only', 'IIS错误解决方案(五):Microsoft JET Database Engine 错误 '80040e09' 不能更新。数据库或对象为只读。', '2012-04-14 07:42:38', '2019-03-25 21:29:22', '原因分析:\r\n未打开数据库目录的读写权限\r\n\r\n解决方法:\r\n( 1 )检查是否在 IIS 中对整个网站打开了 “ 写入 ” 权限,而不仅仅是数据库文件。\r\n( 2 )检查是否在 WIN2000 的资源管理器中,将网站所在目录对 EveryOne 用户打开所有权限。具体方法是:\r\n打开 “ 我的电脑 ”---- 找到网站所在文件夹 ---- 在其上点右键 ---- 选 “ 属性 ”----- 切换到 “ 安全性 ” 选项卡,在这里给 EveryOne 用户所有权限。\r\n\r\n注意:\r\n如果你的系统是 XP ,请先点 “ 工具 ”----“ 文件夹选项 ”----“ 查看 ”----- 去掉 “ 使用简单文件共享 ” 前的勾,确定后,文件夹 “ 属性 ” 对话框中才会有 “ 安全性 ” 这一个选项卡。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2967, 'iis-error-solution-iv-the-microsoft-jet-database-engine-cannot-open-the-file-unknown-it-is-already-opened-exclusively-by-another-user-or-no-permissions-to-view-the-data', 'IIS错误解决方案(四):Microsoft Jet 数据库引擎打不开文件'(未知的)'。 它已经被别的用户以独占方式打开,或没有查看数据的权限。', '2012-04-14 05:56:22', '2019-03-25 21:29:22', '错误类型:\r\nMicrosoft OLE DB Provider for ODBC Drivers (\'0x80004005\')\r\n[Microsoft][ODBC Microsoft Access Driver] Microsoft Jet 数据库引擎打不开文件\'(未知的)\'。 它已经被别的用户以独占方式打开,或没有查看数据的权限。\r\n/conn.asp, 第 6 行\r\n解决方案:\r\nC:WindowsTemp,添加everyone权限!\r\n错误详情:\r\nIIS设置好之后打开ASP网站时总提示:Microsoft OLE DB Provider for ODBC Drivers 错误 \'80004005\'\r\n[Microsoft][ODBC Microsoft Access Driver]常见错误 不能打开注册表关键字 \'Temporary (volatile) Jet DSN for process 0x728 Thread 0x854 DBC 0x276fb44 Jet\'\r\n方法步骤:\r\n1、在WINSOWS/TEMP目录的安全选项中,添加帐号everyone具有可写权限(非NTFS文件系统则跳过此步骤);\r\n2、打开命令提示符,按先后执行如下命令:\r\nregsvr32 jscript.dll\r\nregsvr32 vbscript.dll\r\n
\r\n\r\n  iisreset\r\n   亲测成功!\r\n\r\n
\r\n ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2968, 'asp-database-connection-accesssql-server-2', 'ASP连接Access,Sql Server数据库', '2012-04-14 04:45:45', '2019-03-25 21:29:22', '\"\"\r\n      ASP连接数据库可以使用驱动程序,也可以使用数据源(DateSource,需要在Windows操作系统的控制而板里建立,如果ASP服务器更换需要重新配置才能访问数据库)。不过建议使用驱动程序连接,因为使用驱动程序非常简单,也不会因为ASP移植到其他计算机而重新配置。\r\nODBC连接:\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
数据库连接方式
Access Driver={microsoft access driver (*.mdb)};dbq=路径及文件名;UID=用户名;PWD=密码;
dBaseDriver={microsoft dbase driver (*.mdb)};driverid=用户名;dbq=路径及文件名;
OracleDriver={microsoft odbc for oracle};server=oracleserver.world; UID=用户名;PWD=密码;
MSSQL serverDriver={sql server};servername=服务名;database=数据库名;UID=用户名;PWD=密码;
Visual FoxproDriver={microsoft Visual Foxpro driver};sourcetype=DBC;sourceDB=路径及文件名;exclusive=NO;
MySQLDriver={mysql};database=路径及文件名; UID=用户名;PWD=密码;option=16386;
\r\n \r\n      一般情况下,大多数用户都使用Access数据库来进行测试,所以这里给出一个标准的连接Access数据库的方法:\r\nSet conn = Server.CreateObject(“adodb.connection”)\r\nConn.open = “Driver={microsoft access driver (*.mdb)};dbq=” & Server.mapPath(“/db/bbs.mdb”) & “;UID=用户名;PWD=密码;”\r\n\r\n注意:第二个“driver”和后面的括号之间有一个空格,此空格不能去掉。\r\n\r\nSQL Server连接方法:\r\nSet conn = Server.CreateObject(\"adodb.connection\")\r\nConn.open  \"Driver={sql server}; server=localhost; database=Enroll ;UID=sa;PWD=105036;\"\r\n\r\nRecordset对象方法\r\nOpen方法:\r\nrecordset.Open Source,ActiveConnection,CursorType,LockType,Options \r\nSource \r\n\r\nRecordset对象可以通过Source属性来连接Command对象。Source参数可以是一个Command对象名称、一段SQL命令、一个指定的数据表名称或是一个Stored Procedure。假如省略这个参数,系统则采用Recordset对象的Source属性。 \r\n\r\nActiveConnection \r\n\r\nRecordset对象可以通过ActiveConnection属性来连接Connection对象。这里的ActiveConnection可以是一个Connection对象或是一串包含数据库连接信息(ConnectionString)的字符串参数。 \r\n\r\nCursorType \r\n\r\nRecordset对象Open方法的CursorType参数表示将以什么样的游标类型启动数据,包括adOpenForwardOnly、adOpenKeyset、adOpenDynamic及adOpenStatic,分述如下: \r\n\r\n-------------------------------------------------------------- \r\n\r\n常数 常数值 说明 \r\n\r\n------------------------------------------------------------- \r\n\r\nadOpenForwardOnly 0 缺省值,启动一个只能向前移动的游标(Forward Only)。 \r\n\r\nadOpenKeyset 1 启动一个Keyset类型的游标。 \r\n\r\nadOpenDynamic 2 启动一个Dynamic类型的游标。 \r\n\r\nadOpenStatic 3 启动一个Static类型的游标。 \r\n\r\n------------------------------------------------------------- \r\n\r\n以上几个游标类型将直接影响到Recordset对象所有的属性和方法,以下列表说明他们之间的区别。 \r\n\r\n \r\n\r\n------------------------------------------------------------- \r\n\r\nRecordset属性 adOpenForwardOnly adOpenKeyset adOpenDynamic adOpenStatic \r\n\r\n------------------------------------------------------------- \r\n\r\nAbsolutePage 不支持 不支持 可读写 可读写 \r\n\r\nAbsolutePosition 不支持 不支持 可读写 可读写 \r\n\r\nActiveConnection 可读写 可读写 可读写 可读写 \r\n\r\nBOF 只读 只读 只读 只读 \r\n\r\nBookmark 不支持 不支持 可读写 可读写 \r\n\r\nCacheSize 可读写 可读写 可读写 可读写 \r\n\r\nCursorLocation 可读写 可读写 可读写 可读写 \r\n\r\nCursorType 可读写 可读写 可读写 可读写 \r\n\r\nEditMode 只读 只读 只读 只读 \r\n\r\nEOF 只读 只读 只读 只读 \r\n\r\nFilter 可读写 可读写 可读写 可读写 \r\n\r\nLockType 可读写 可读写 可读写 可读写 \r\n\r\nMarshalOptions 可读写 可读写 可读写 可读写 \r\n\r\nMaxRecords 可读写 可读写 可读写 可读写 \r\n\r\nPageCount 不支持 不支持 只读 只读 \r\n\r\nPageSize 可读写 可读写 可读写 可读写 \r\n\r\nRecordCount 不支持 不支持 只读 只读 \r\n\r\nSource 可读写 可读写 可读写 可读写 \r\n\r\nState 只读 只读 只读 只读 \r\n\r\nStatus 只读 只读 只读 只读 \r\n\r\nAddNew 支持 支持 支持 支持 \r\n\r\nCancelBatch 支持 支持 支持 支持 \r\n\r\nCancelUpdate 支持 支持 支持 支持 \r\n\r\nClone 不支持 不支持 \r\n\r\nClose 支持 支持 支持 支持 \r\n\r\nDelete 支持 支持 支持 支持 \r\n\r\nGetRows 支持 支持 支持 支持 \r\n\r\nMove 不支持 支持 支持 支持 \r\n\r\nMoveFirst 支持 支持 支持 支持 \r\n\r\nMoveLast 不支持 支持 支持 支持 \r\n\r\nMoveNext 支持 支持 支持 支持 \r\n\r\nMovePrevious 不支持 支持 支持 支持 \r\n\r\nNextRecordset 支持 支持 支持 支持 \r\n\r\nOpen 支持 支持 支持 支持 \r\n\r\nRequery         支持    支持    支持    支持 \r\n\r\nResync        不支持   不支持   支持   支持 \r\n\r\nSupports        支持     支持    支持    支持 \r\n\r\nUpdate         支持     支持    支持    支持 \r\n\r\nUpdateBatch    支持     支持    支持    支持 \r\n\r\n-------------------------------------------------------------- \r\n\r\n其中NextRecordset方法并不适用于Microsoft Access数据库。 \r\n\r\nLockType \r\n\r\nRecordset对象Open方法的LockType参数表示要采用的Lock类型,如果忽略这个参数,那么系统会以Recordset对象的LockType属性为预设值。LockType参数包含adLockReadOnly、adLockPrssimistic、adLockOptimistic及adLockBatchOptimistic等,分述如下: \r\n\r\n \r\n\r\n------------------------------------------------------------- \r\n\r\n常数 常数值 说明 \r\n\r\n-------------------------------------------------------------- \r\n\r\nadLockReadOnly 1 缺省值,Recordset对象以只读方式启动,无法运行AddNew、Update及Delete等方法 \r\n\r\nadLockPrssimistic 2 当数据源正在更新时,系统会暂时锁住其他用户的动作,以保持数据一致性。 \r\n\r\nadLockOptimistic 3 当数据源正在更新时,系统并不会锁住其他用户的动作,其他用户可以对数据进行增、删、改的操作。 \r\n\r\nadLockBatchOptimistic 4 当数据源正在更新时,其他用户必须将CursorLocation属性改为adUdeClientBatch才能对数据进行增、 \r\n\r\n删、改的操作。 \r\n\r\n记录集对象的方法: \r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
rs.movenext将记录指针从当前的位置向下移一行
rs.moveprev将记录指针从当前的位置向上移一行
rs.movefirst将记录指针移到记录集第一行
rs.movelast将记录指针移到记录集最后一行
rs.move[i]将记录指针下移i行
rs.move i,start将记录指针从start 开始下移i行
rs.absoluteposition=n将记录指针移到记录集第n行
rs.absolutepage=n将记录指针移到第n页的第一行
rs.pagesize=n设置每页为n条记录
rs.pagecount根据 pagesize 的设置返回总页数
rs.recordcount返回记录总数
rs.bof返回记录指针是否超出记录集首端,true表示是,false为否
rs.eof返回记录指针是否超出记录集末端,true表示是,false为否
rs.delete删除当前记录,但记录指针不会向下移动
rs.addnew添加记录到记录集末端
rs.update更新记录集记录
rs.fields.count返回字段数
rs.(i).name返回第i个字段的字段名
rs.(i)返回第i个字段的值
rs(“字段名”)返回该字段的值
rs.open打开recordset 对象,执行查询
rs.close关闭 recordset 对象
\r\n \r\n\r\n \r\n\r\nRS.OPEN   SQL,CONN,A,B\r\n\r\nA:\r\n\r\nADOPENFORWARDONLY(=0)\r\n只读,且当前数据记录只能向下移动\r\n\r\nADOPENKEYSET(=1)\r\n只读,当前数据记录可自由移动\r\n\r\nADOPENDYNAMIC(=2)\r\n可读写,当前数据记录可自由移动\r\n\r\nADOPENSTATIC(=3)\r\n可读写,当前数据记录可自由移动,可看到新增记录\r\n\r\nB:\r\n\r\nADLOCKREADONLY(=1)\r\n缺省锁定类型,记录集是只读的,不能修改记录\r\n\r\nADLOCKPESSIMISTIC(=2)\r\n悲观锁定,当修改记录时,数据提供者将尝试锁定记录以确保成功地编辑记录。只要编辑一开始,则立即锁住记录。\r\n\r\nADLOCKOPTIMISTIC(=3)\r\n乐观锁定 ,直到用Update方法提交更新记录时才锁定记录。\r\n\r\nADLOCKBATCHOPTIMISTIC(=4)\r\n批量乐观锁定,允许修改多个记录,只有调用UpdateBatch方法后才锁定记录。\r\n\r\n当不需要改动任何记录时,应该使用只读的记录集,这样提供者不用做任何检测。\r\n对于一般的使用,乐观的锁定可能是最好的选择,因为记录只被锁定一小段时间,\r\n数据在这段时间被更新。这减少了资源的使用。\r\n\r\n应用实例:\r\nASP连接Access数据库\r\n<%@LANGUAGE=\"VBSCRIPT\" CODEPAGE=\"65001\"%>\r\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\r\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\r\n<head>\r\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\r\n<title>Access数据库连接测试</title>\r\n</head>\r\n<body>\r\n<center>Access数据库连接成功!</center>\r\n\r\n<%\r\nDim conn\r\nSet conn = Server.CreateObject(\"adodb.connection\")\r\nConn.open = \"Driver={microsoft access driver (*.mdb)};dbq=\" & Server.mapPath(\"xhnew.mdb\") & \";UID=;PWD=;\"\r\n%>\r\n\r\n</body>\r\n</html>\r\n\"\"\r\n\r\nASP连接Sql Server数据库\r\n<%@LANGUAGE=\"VBSCRIPT\" CODEPAGE=\"65001\"%>\r\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\r\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\r\n<head>\r\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\r\n<title>Sql Server数据库连接测试</title>\r\n</head>\r\n<body>\r\n<center>Sql Server数据库连接成功!</center>\r\n\r\n<%\r\nDim conn\r\nSet conn = Server.CreateObject(\"adodb.connection\")\r\nConn.open  \"Driver={sql server}; server=localhost; database=Enroll ;UID=sa;PWD=105036;\"\r\n%>\r\n\r\n</body>\r\n</html>\r\n\"\"\r\n\r\n ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2969, 'iis-error-solution-iii-occurs-after-you-reload-iis6-0-this-snapin-mmc-detected-an-error-occurred-suggest-that-you-shut-down-and-restart-mmc', 'IIS错误解决方案(三):重装IIS6.0后出现MMC检测到此管理单元发生一个错误。建议你关闭并重新启动MMC。', '2012-04-14 02:27:11', '2019-03-25 21:29:22', '
      要变通解决此问题, 请按照下列步骤操作进入 WMI MMC 管理单元:\r\n1. 开始——运行——输入mmc然后单击 确定 。\r\n2. 在 文件 菜单上, 单击 \" 添加/删除管理单元 。\r\n3. 在 添加/删除管理 - 中 对话框中, 单击 添加 。\r\n4. 在 可用的独立管理单元 列表, 选择 WMI 控制 , 并单击 确定 。\r\n      问题解决!\r\n\r\n      如果上述不能解决请尝试以下方法(适用于XP系统):\r\n1. 单击“开始”,单击“运行”,键入 regedit,然后单击“确定”。\r\n2. 在左窗格中,找到以下注册表子项,然后单击它:\r\nHKEY_LOCAL_MACHINESOFTWAREMicrosoftMMC\r\n3. 在“编辑”菜单上,指向“新建”,然后单击“项”。\r\n4. 键入 UseNewUI 作为新名称,然后按 Enter。\r\n5. 在“文件”菜单上,单击“退出”。
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2970, 'how-do-i-disable-the-notebook-comes-with-keyboard', '如何禁止笔记本自带键盘', '2012-04-12 22:55:03', '2019-03-25 21:29:22', '\"\"\r\n笔记本键盘有点失灵,很多时候会自己冒出几个键,很是烦人。想把笔记自带的键盘禁止掉,今天在网上查了查,很多都是说拆开笔记本把信号线拔掉。最后终于找了一个不这么暴力且简单易行的方法,本人已经试验过了。特分享出来!\r\n步骤1:右击“桌面”上的“我的电脑”点击“属性”;\r\n步骤2:在打开的“系统属性”选项卡中点击“硬件”中的“设备管理器”;\r\n步骤3:在打开的“设备管理器”的“键盘”中右击你的笔记本自带的键盘(如果不知道哪个是你的外置键盘,要先把外置键盘把下来,剩下的就是你笔记本的内置键盘)的“属性”;\r\n步骤4:点击“更新驱动程序” 选择”否,暂时不”,并且点击“下一步”;\r\n步骤5: 选择“从列表或指定位置安装(高级)”,并且点击“下一步”;\r\n步骤6:选择“不要搜索,我要自己选择要安装的驱动程序”,并且点击“下一步”;\r\n步骤7:将图示勾选的“显示兼容硬件”取消,选择其中任意一个非兼容硬件,例如“Acer”,然后点击“下一步”;\r\n步骤8:出现警告提示,选择“是”,系统自动更新软件,点击“完成”,注意只有重新启动电脑,设置才能够更新;\r\n步骤9:暂时不重启电脑,选择“否“,关闭设备管理器和控制面板后,关闭电脑;\r\n完成:关闭电脑后,连接外接USB键盘,然后开机,外置键盘可以正常使用,内置键盘已经失效成功!!!\r\n注意:有些安全性比较高的网站例如银行等需要笔记本自带的键盘输入,另外也很可能造成丢失系统设置的一些权限后果自负!', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2972, 'android-sdk-directory-and-install-apk-package-directory-details-2', 'Android SDK目录及APK安装包目录详解', '2012-04-11 05:03:05', '2019-03-25 21:29:22', 'Android SDK目录详解:\r\n\"\"\r\n      1. add-ons/ 这里面保存着你开发附加应用或者在其它设备上开发Android应用时需要的附加类库,比如google Maps,当然你如果安装了OPhone SDK,这里也会有一些类库在里面。\r\n      2. docs/ 这里面包括开发指南、Android SDK API参考文档等,所有的API都可以在这里查到。\r\n      3. extras/ Android SDK的附加组件。\r\n      4. platforms/ 是每个平台的SDK真正的文件,里面会根据API Level划分的SDK版本,以Android 2.2来说,进入后有一个android-8的文件夹,android-8进入后是Android 2.2 SDK的主要文件,其中ant为ant编译脚本,data保存着一些系统资源,images是模拟器映像文件,skins则是Android模拟器的皮肤,templates是工程创建的默认模板,android.jar则是该版本的主要framework文件。\r\n      5. platform-tools/ 保存着一些通用工具,比如adb、和aapt、aidl、dx等文件。\r\n      6. samples/ 是Android SDK自带的默认示例工程,里面的apidemos适合初学者运行学习,对于SQLite数据库操作可以查看NotePad这个例子,对于游戏开发Snake、LunarLander都是不错的例子,对于Android主题开发Home则是android m5时代的主题设计原理。\r\n7.system-images/ 更新版本产生的系统资源、映像等等。\r\n8.temp/ 更新SDK时的临时文件存放文件夹。\r\n      9. tools/ 作为SDK根目录下的tools文件夹,这里包含了重要的工具,比如ddms用于启动Android调试工具,比如logcat、屏幕截图和文件管理器,而draw9patch则是绘制android平台的可缩放png图片的工具,sqlite3可以在PC上操作SQLite数据库,而monkeyrunner则是一个不错的压力测试应用,模拟用户随机按键,mksdcard则是模拟器SD映像的创建工具,emulator是android模拟器主程序,不过从android 1.5开始,需要输入合适的参数才能启动模拟器,traceview作为android平台上重要的调试工具。\r\n      10.AVD Manager.exe 创建安卓模拟器的工具。\r\n11.SDK Manager.exe 更新Android SDK的工具。\r\n12.SDK Readme.txt 安卓版本的说明文件。\r\n\r\n安装包(apk)目录结构详解:\r\n\r\n      1. META-INF  Jar文件中常可以看到;\r\n\r\n      2. res  存放资源文件的目录);\r\n\r\n      3. AndroidManifest.xml 程序全局配置文件 ;\r\n\r\n      4. classes.dex Dalvik字节码;\r\n\r\n      5. resources.arsc 编译后的二进制资源文件。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2974, 'failed-to-fetch-url-httpdl-ssl-google-com-android-android-sdk-installation-repository-addons-list-1-xml-solutions', '安装Android SDK出现Failed to fetch URL http://dl-ssl.google.com/android/repository/addons_list-1.xml解决方案', '2012-04-09 22:43:52', '2019-03-25 21:29:22', '      最近有一个项目要用安卓开发,记得以前装过Android SDK,今天照例。先下载Eclipse,又装好了ADT,可是在装Android SDK时却出现了\r\nFetching http://dl-ssl.google.com/android/repository/addons_list-1.xml\r\nFailed to fetch URL http://dl-ssl.google.com/android/repository/addons_list-1.xml, reason: Connection to http://dl-ssl.google.com refused\r\nFetched Add-ons List successfully\r\nFetching URL: http://dl-ssl.google.com/android/repository/repository-6.xml\r\nFailed to fetch URL http://dl-ssl.google.com/android/repository/repository-6.xml, reason: Connection to http://dl-ssl.google.com refused\r\nDone loading packages.\r\n\"\"\r\n      网上查资料,终于在谷歌官网找到了答案\r\nhttp://code.google.com/p/android/issues/detail?can=2&start=0&num=100&q=&colspec=ID%20Type%20Status%20Owner%20Summary%20Stars&groupby=&sort=&id=21359\r\n具体操作:\r\n•用记事本或Gvim打开C:WINDOWSsystem32driversetc中的hosts文件\r\n•在最后一行添加74.125.237.1 dl-ssl.google.com\r\n•成功解决问题。\r\n\"\"', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2975, 'eclipse3-7-installation-adt16-org-eclipse-wst-sse-core-0-0-0-encountered-lack-of-a-solution', 'eclipse3.7安装ADT16时遇到org.eclipse.wst.sse.core 0.0.0缺失的一个解决方案', '2012-04-09 21:17:36', '2019-03-25 21:29:22', '安装环境:\r\n操作系统:Windows XP SP3\r\nEclipse 3.7\r\n问题描述:\r\n安装ADT16时遭遇“requires \'org.eclipse.wst.sse.core 0.0.0\'”问题。\r\n\"\"\r\n解决方法:\r\n1.点击Help->Install New Software->”Available Software Sites”->Add按钮下方的“Available Software Sites”,选中Helios Milestone Repository http://download.eclipse.org/releases/indigo\r\n2.回到安装插件的界面,确保最下方复选框\"Contact all update site during install to find required software\"\r\n\"\"\r\n再Next,这次应该OK了,如果不OK,可能就是网络问题。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2976, 'program-computational-1-1-21-4-1-99-1-100-until-the-last-one-of-absolute-value-less-than-1-10000', '编程“计算1-1/2+1/3-1/4+...+1/99-1/100+...直到最后一项的绝对值小于1/10000为止。', '2012-04-07 07:47:48', '2019-03-25 21:29:22', '
public class Plus1\r\n{\r\npublic static void main(String[] args) //Main方法\r\n{\r\nPlus1 p1 = new Plus1();\r\ndouble t;\r\nt = p1.Plus1Method();\r\nSystem.out.println(\"1-1/2+1/3-1/4+…+1/99-1/100+…=\" + t);\r\n}    public double Plus1Method()// 计算1-1/2+1/3-1/4+…+1/99-1/100+…,直到最后一项的绝对值小于10-4为止。\r\n{\r\ndouble sum = 0.0;\r\ndouble epsilon = 1.0e-4;\r\ndouble flag = 1.0;\r\nint loopNum = (int) (1.0 / epsilon);\r\n\r\nfor (int i = 1; i <= loopNum; i++)\r\n{\r\nsum += flag / (double) i;\r\nflag = -flag;\r\n}\r\nreturn sum;\r\n}\r\n}\r\n\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2977, 'java-format-output-details', 'Java格式化输出详解', '2012-03-31 01:10:56', '2019-03-25 21:29:22', '      Java的格式化输出等同于String.Format,与C有很大的相似,比如:\r\nSystem.out.printf(\"%8.2f\", x);\r\n      在printf中,可以使用多个参数,例如:\r\nSystem.out.printf(\"Hello, %s. Next year, you\'ll be %d\", name, age);\r\n用于printf的转换符如下表:\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
转换符类型 举例
d十进制整数  159
x十六进制整数9f
o八进制整数237
f定点浮点数15.9
e指数浮点数1.59e+01
g通常浮点数 
a十六进制浮点数0x1.fccdp3
s字符串Hello
c字符H
b布尔型TRue
h散列码42628b2
tx日期时间见时间介绍表
%百分号%
n分隔符      
\r\n
\r\n\r\n  在printf函数中,可以使用多个标志,如:\r\nSystem.out.printf(\"%,.2f\", 10000.0 / 3.0);\r\n用于printf的标志如下表\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
标志目的举例
+打印数字前的符号+3333.33
space在正数之前加空格| 3333.33|
0在数字前补0003333.33
-左对齐|3333.33 |
(负数括在括号内(3333.33)
,添加分组分隔符3,333.33
# (for f )包含小数点3,333.
# (for x or o)添加前缀 0x 或 00xcafe
^转化为大写0XCAFE
$指定格式化参数索引,如%1$d,%1$d表示以十进制\r\n和十六进制打印第一个参数159 9F
<格式化前面参数,如%d%<x表示以十进制和十六进\r\n制打印同一个参数159 9F
\r\n  时间日期的转换符如下:\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
转换符类型举例
C完整日期和时间Mon Feb 09 18:05:19 PST 2004
FISO 8601 日期2004-02-09
D美国时间格式 (mm/dd/year)02/09/2004
T24小时时间18:05:19
r12小时时间06:05:19 pm
R24小时无秒时间18:05
Y四位年2004
y年的后两位04
C年的前两位20
B月的完整拼写February
b or h月的缩写Feb
m两位月(前补0)02
d两位日(前补0)09
e日期(前不补0)9
A完整星期几Monday
a星期几的缩写Mon
j这一年的第多少天,三位补0069
H24小时制小时,两位补018
k24小时制小时,两位不补018
I12小时制小时,两位补006
l12小时制小时,两位不补06
M分钟,两位补005
S秒,两位补019
L毫秒,三位补0047
N毫微秒,九位补0047000000
P上下午大写PM
p上下午小写pm
zRFC 822 numeric offset from GMT-0800
Z时区PST
s1970-01-01 00:00:00起秒数1078884319
E1970-01-01 00:00:00起毫秒数1078884319047
\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2978, 'sanyuan-group-creation-and-basic-operation', '三元组的创建及基本操作', '2012-03-30 05:58:30', '2019-03-25 21:29:22', '源码:\r\n
#include \"stdlib.h\"
\r\n#include <iostream>
\r\nusing namespace std;
\r\n#define OK 1
\r\n#define OVERFLOW -2
\r\n#define ERROR -1
\r\ntypedef int *Triplet;
\r\n
\r\nint InitTriplet(Triplet &T, int v1, int v2, int v3)//初始化
\r\n{
\r\n    T = (int *malloc(3 * sizeof (int));
\r\n    if (!Texit(OVERFLOW);
\r\n    T[0] = v1;
\r\n    T[1] = v2;
\r\n    T[2] = v3;
\r\n    return OK;
\r\n}
\r\n
\r\nint DestroyTriplet(Triplet &T)//销毁
\r\n{
\r\n    free(T);
\r\n    T = NULL;
\r\n    return OK;
\r\n}
\r\n
\r\nint Get(Triplet T, int i, int &e)//获取
\r\n{
\r\n    if (i < 1 || i > 3return ERROR;
\r\n    e = T[i - 1];
\r\n    return OK;
\r\n}
\r\n
\r\nint Put(Triplet &T, int i, int e)//插入
\r\n{
\r\n    if (i < 1 || i > 3return ERROR;
\r\n    T[i - 1] = e;
\r\n    return OK;
\r\n}
\r\n
\r\nbool IsAscending(Triplet T)//是否递增排列
\r\n{
\r\n    return T[0] <= T[1] && T[1] <= T[2];
\r\n}
\r\n
\r\nbool IsDecending(Triplet T)//是否递减排列
\r\n{
\r\n    return T[0] >= T[1] && T[1] >= T[2];
\r\n}
\r\n
\r\nint Max(Triplet T, int &e)//最大值
\r\n{
\r\n    if (T[0] >= T[1])
\r\n        e = T[0];
\r\n    else e = T[1];
\r\n    if (e < T[2])
\r\n        e = T[2];
\r\n    return OK;
\r\n}
\r\n
\r\nint Min(Triplet T, int &e)//最小值
\r\n{
\r\n    if (T[0] <= T[1])
\r\n        e = T[0];
\r\n    else e = T[1];
\r\n    if (e > T[2])
\r\n        e = T[2];
\r\n    return OK;
\r\n}
\r\n
\r\nint main()//主函数
\r\n{
\r\n    Triplet t;
\r\n    InitTriplet(t, 5, 8, 6);
\r\n    Put(t, 1, 4);
\r\n    Put(t, 2, 5);
\r\n    int m;
\r\n    Max(t, m);
\r\n    cout << \"三元组中所有元素如下:\"<<endl;
\r\n    for (int i = 0i < 3i++{
\r\n        cout << t[i];
\r\n        cout << endl;
\r\n    }
\r\n    cout << \"该三元组中最大元素是:\";
\r\n    cout << m << endl;
\r\n    system(\"pause\");
\r\n    return 0;
\r\n}
\r\n演示:\r\n\"\"', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2979, 'immediately-set-the-variables-x-and-y-are-independent-normally-distributed-xn-35-yn-720-calculation-of-probabilities-p-xy', '设随即变量X与Y相互独立,都服从正态分布。其中X~N(3,5),Y~N(7,20)。计算概率P(X+Y', '2012-03-30 04:18:05', '2019-03-25 21:29:22', '题目:\r\n设随即变量X与Y相互独立,都服从正态分布。其中X~N(3,5),Y~N(7,20)。计算概率P(X+Y<=15)。\r\n答案与解析:\r\n如果X和Y相互独立,那么正态公布对两个参数有可加性。\r\n已知:XN(3,5),YN(7,20)\r\n那么X+Y有,N(μ1+μ2,σ1(2)+σ2(2)),μ1+μ2=3+7,σ1(2)+σ2(2)=5+20,\r\n所以X+Y~N(10,25).\r\n求的是X+Y≤15,\r\n就是求Φ((15-10)/5)=Φ(1)=0.8413', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2980, 'how-to-solve-the-problem-of-mspdb100-dll-not-found-in-vs2010-and-how-to-make-the-cl-exe-and-dumpbin-exe-to-work-under-dos', '如何解决vs2010中mspdb100.dll找不到的问题,及如何使cl.exe和dumpbin.exe在dos下工作', '2012-03-27 06:42:28', '2019-03-25 21:29:22', ' \r\n\r\n\r\n\r\n\r\n\r\n\r\n
问题】安装VS 2010后,运行dumpbin,出现错误:没有找到mspdb100.dll,因此这个应用程序未能启动。重新安装应用程序可能会修复此问题\r\n\r\n【经过】\r\n\r\n之前正常安装了VS 2010,安装在了D盘下面。\r\n\r\n现在想去测试一个命令行下面的工具,dumpbin.exe,\r\n\r\n直接开始->运行->cmd,然后输入dumpbin,显示不是可执行程序。\r\n\r\n所以,去安装目录搜了下,找到了dumpbin所在目录:\r\n\r\nD:Program FilesMicrosoft Visual Studio 10.0VCbin\r\n\r\n将其添加到系统的环境变量Path中后,然后再去cmd中输入dumpbin,可以找到了。\r\n\r\n但是却会出错,弹出个对话框:\r\n\r\n\"如何解决mspdb100.dll找不到的问题,及如何使cl.exe和dumpbin.exe\r\n\r\n网上找了半天,貌似有人说,可以将对应的mspdb100.dll以及其他一些必须的dll等文件拷贝过去,但是去VS 2010的安装源文件(ISO文件)中,没有找到这些dll文件,后来想起来了,去其安装目录中找,果然找到了,在这里:\r\n\r\nD:Program FilesMicrosoft Visual Studio 10.0Common7IDE\r\n\r\n但是,觉得不应该直接拷贝吧,正常安装VS 2010,安装过程一直很正常,又没有出错,不应该不能使用其下的一些命令行工具的啊。\r\n\r\n【解决过程】\r\n\r\n后来巧了,看到这个帖子:\r\n\r\n在低版本的 vc 中使用 vc 10.0 的新特性\r\n\r\nhttp://www.cnblogs.com/wuerping/archive/2009/06/08/1498392.html\r\n\r\n中提到的“。。。 Tools->Projects and Solutions->VC++ Directories->Executable files->$(VCInstallDir)bin,。。。”,去开始->所有程序->Microsoft Visual Studio 2010->Visual Studio Tools,有对应的命令行开发环境,Visual Studio 命令提示(2010),所以,运行“Visual Studio 命令提示(2010)”后,就像普通的cmd一样的命令行环境,就可以正常使用那些工具,包括dumpbin了。\r\n\r\n另外,去看了一下,“Visual Studio 命令提示(2010)”对应的是这个可执行程序:\r\n\r\n%comspec% /k \"\"D:Program FilesMicrosoft Visual Studio 10.0VCvcvarsall.bat\"\" x86\r\n\r\n最后,贴上dumpbin的运行时输出:\r\n\r\nSetting environment for using Microsoft Visual Studio 2010 x86 tools.\r\n\r\nD:Program FilesMicrosoft Visual Studio 10.0VC>dumpbin\r\nMicrosoft (R) COFF/PE Dumper Version 10.00.30319.01\r\nCopyright (C) Microsoft Corporation. All rights reserved.\r\n\r\n用法: DUMPBIN [选项] [文件]\r\n\r\n   选项:\r\n\r\n      /ALL\r\n/ARCHIVEMEMBERS\r\n/CLRHEADER\r\n/DEPENDENTS\r\n/DIRECTIVES\r\n/DISASM[:{BYTES|NOBYTES}]\r\n/ERRORREPORT:{NONE|PROMPT|QUEUE|SEND}\r\n/EXPORTS\r\n/FPO\r\n/HEADERS\r\n/IMPORTS[:文件名]\r\n/LINENUMBERS\r\n/LINKERMEMBER[:{1|2}]\r\n/LOADCONFIG\r\n/OUT:文件名\r\n/PDATA\r\n/PDBPATH[:VERBOSE]\r\n/RANGE:vaMin[,vaMax]\r\n/RAWDATA[:{NONE|1|2|4|8}[,#]]\r\n/RELOCATIONS\r\n(按回车键继续)\r\n/SECTION:名称\r\n/SUMMARY\r\n/SYMBOLS\r\n/TLS\r\n/UNWINDINFO
\r\n ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2981, 'sql-server-2008-does-not-allow-you-to-save-the-changes-and-changes-you-request-delete-and-then-create-the-following-table-of-solutions', 'Sql Server 2008不允许保存更改,您所做的更改要求删除并重新创建以下表的解决办法', '2012-03-26 23:17:00', '2019-03-25 21:29:22', '
\r\n\r\n启动SQL Server 2008 Management Studio\r\n工具菜单----选项----Designers(设计器)----阻止保存要求重新创建表的更改  取消勾选即可。\r\n\r\n\"\"\r\n\r\n
\r\n
 
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2982, 'created-with-mysql-databases-and-database-tables', '用MySQL创建数据库和数据库表', '2012-03-26 05:49:34', '2019-03-25 21:29:22', '\r\n\r\n\r\n\r\n\r\n\r\n
    1、使用SHOW语句找出在服务器上当前存在什么数据库:\r\n\r\n<ccid_nobr>\r\n\r\n\r\n\r\n\r\n\r\n\r\n
\r\n
<ccid_code>mysql> SHOW DATABASES;\r\n+----------+\r\n| Database |\r\n+----------+\r\n| mysql |\r\n| test |\r\n+----------+\r\n3 rows in set (0.00 sec)
\r\n
\r\n \r\n\r\n    2、创建一个数据库abccs\r\nmysql> CREATE DATABASE abccs;\r\n注意不同操作系统对大小写的敏感。\r\n\r\n    3、选择你所创建的数据库\r\nmysql> USE abccs\r\nDatabase changed\r\n此时你已经进入你刚才所建立的数据库abccs.\r\n\r\n    4、 创建一个数据库表\r\n\r\n    首先看现在你的数据库中存在什么表:\r\nmysql> SHOW TABLES;\r\nEmpty set (0.00 sec)\r\n说明刚才建立的数据库中还没有数据库表。下面来创建一个数据库表mytable:\r\n我们要建立一个你公司员工的生日表,表的内容包含员工姓名、性别、出生日期、出生城市。\r\n\r\n<ccid_nobr>\r\n\r\n\r\n\r\n\r\n\r\n\r\n
\r\n
<ccid_code>mysql> CREATE TABLE mytable (name VARCHAR(20), sex CHAR(1),\r\n-> birth DATE, birthaddr VARCHAR(20));\r\nQuery OK, 0 rows affected (0.00 sec)
\r\n
\r\n \r\n\r\n    由于name、birthadd的列值是变化的,因此选择VARCHAR,其长度不一定是20。可以选择从1到255的任何长度,如果以后需要改变它的字长,可以使用ALTER TABLE语句。);性别只需一个字符就可以表示:\"m\"或\"f\",因此选用CHAR(1);birth列则使用DATE数据类型。\r\n\r\n    创建了一个表后,我们可以看看刚才做的结果,用SHOW TABLES显示数据库中有哪些表:\r\n\r\n<ccid_nobr>\r\n\r\n\r\n\r\n\r\n\r\n\r\n
\r\n
<ccid_code>mysql> SHOW TABLES;\r\n+---------------------+\r\n| Tables in menagerie |\r\n+---------------------+\r\n| mytables |\r\n+---------------------+
\r\n
\r\n \r\n\r\n    5、显示表的结构:\r\n\r\n<ccid_nobr>\r\n\r\n\r\n\r\n\r\n\r\n\r\n
\r\n
<ccid_code>mysql> DESCRIBE mytable;\r\n+-------------+-------------+------+-----+---------+-------+\r\n| Field | Type | Null | Key | Default | Extra |\r\n+-------------+-------------+------+-----+---------+-------+\r\n| name | varchar(20) | YES | | NULL | |\r\n| sex | char(1) | YES | | NULL | |\r\n| birth | date | YES | | NULL | |\r\n| deathaddr | varchar(20) | YES | | NULL | |\r\n+-------------+-------------+------+-----+---------+-------+\r\n4 rows in set (0.00 sec)
\r\n
\r\n \r\n\r\n    6、 往表中加入记录\r\n\r\n    我们先用SELECT命令来查看表中的数据:\r\nmysql> select * from mytable;\r\nEmpty set (0.00 sec)\r\n这说明刚才创建的表还没有记录。\r\n\r\n    加入一条新记录:\r\n\r\n<ccid_nobr>\r\n\r\n\r\n\r\n\r\n\r\n\r\n
\r\n
<ccid_code>mysql> insert into mytable\r\n-> values (′abccs′,′f′,′1977-07-07′,′china′);\r\nQuery OK, 1 row affected (0.05 sec)
\r\n
\r\n \r\n\r\n    再用上面的SELECT命令看看发生了什么变化。我们可以按此方法一条一条地将所有员工的记录加入到表中。\r\n\r\n    7、用文本方式将数据装入一个数据库表\r\n\r\n    如果一条一条地输入,很麻烦。我们可以用文本文件的方式将所有记录加入你的数据库表中。创建一个文本文件“mysql.txt”,每行包含一个记录,用定位符(tab)把值分开,并且以在CREATE TABLE语句中列出的列次序给出,例如:\r\n\r\n<ccid_nobr>\r\n\r\n\r\n\r\n\r\n\r\n\r\n
\r\n
<ccid_code>abccs f 1977-07-07 china  \r\nmary f 1978-12-12 usa\r\ntom m 1970-09-02 usa
\r\n
\r\n \r\n\r\n    使用下面命令将文本文件“mytable.txt”装载到mytable表中:mysql> LOAD DATA LOCAL INFILE \"mytable.txt\" INTO TABLE pet;\r\n\r\n    再使用如下命令看看是否已将数据输入到数据库表中:mysql> select * from mytable;
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2983, 'win7-aspaccess-environment-in-iis7-configuration', 'Win7下IIS7中ASP+ACCESS环境的配置', '2012-03-26 00:37:32', '2019-03-25 21:29:22', '      Win7下的IIS只需要在 \"打开关闭 Windows 功能\" 中启用即可,具体方法如下:\r\n首先单击开始,打开控制面板,在控制面板中单击程序。注意查看方式是类别。\r\n\r\n\"image\"\r\n\r\n      接着单击打开或关闭windows功能\r\n\r\n\"image\"\r\n\r\n      找到internet信息服务,若要打开它,选择前面的复选框即可。选好后确定,IIS就打开了。若要关闭,清楚其复选框即可。\r\n\r\n\"image\"\r\n      IIS 安装成功后像从前那样修改默认站点的虚拟目录和默认文档, 指向网站安装目录,这时网站可以打开, 但数据库却无法连接.\r\n      此时进入IIS设置, 在网站默认设置或站点的基本设置中, 将 \"应用程序池\" 从 \"DefaultAppPool\" 改为 \"Classic .NET AppPool\". (见注一)\r\n      点击站点 - 双击在 IIS 组里的 ASP 图标 - 展开 \"行为\" - 将 \"启用父路径\" 设为 \"True\".\r\n展开 ASP 的 \"限制属性\", 将其中的 \"最大请求实体主体限制\" 从 \"200000\" 改为更高. (增大         上传文件体积限制, 可选)\r\n      在文件夹选项里显示隐藏文件, 然后给 \"系统盘:WindowsServiceProfilesNetworkServiceAppDataLocalTemp\" 目录添加一个 \"Authenticated Users\" 的用户, 并为其赋予 \"完全控置\" 的权限.\r\n额外的, 为 Dutory 新建一站点 (不是虚拟目录) 时, 无使用任意可用 IP + 其它端口, 如 *:8008, 只能指定一具体 IP, 如 192.168.1.202:8008. 这个注意下.\r\n\r\n      注一: 如果不小心在 \"应用程序池中\" 删掉了 \"Classic .NET AppPool\", 或改乱了配置. 只要添加一个应用程序池, 随便起个名, 比如 \"esloy.web\", 在 \"基本设置\" 中将 \"托管管道模式\" 设为 \"经典\", 然后在网站或站点设置中将 \"应用程序池\" 设为 \"esloy.web\". 也是一样. 实际上, 我就是设为 \"DefaultAppPool\" 也照常使用, 没发现有什么不同.\r\n\r\n附: 在 NTFS 分区中为 IIS (ACCESS 连接) 配置权限:\r\n      文件夹选项->查看 把文件的简单共享去掉 (2K/XP)\r\n      右击数据库目录, 在安全选项卡里, 加上IUSR_XX (XX为你的机器名) 的可修改权限. (也可直接加入 guests 组或 everyone 修改权限. 不推荐)\r\n      给 \"系统盘:windowstemp\" 文件夹加上everyone的完全控制权限. (2003)\r\n      补充一个另外的错误, 重新注册VB和JS运行库, 可能用得到:(过程很痛苦,不多说,以下面这个错误开始:\r\n      Microsoft OLE DB Provider for ODBC Drivers 错误 \'80004005\' \r\n      [Microsoft][ODBC Microsoft Access Driver] Microsoft Jet 数据库引擎打不开文件\'(未知的)\'。它已经被别的用户以独占方式打开,或没有查看数据的权限。 \r\n      我想这个错误对于使用win7又想用ASP+Access的人来说就像每天早餐吃面包加牛奶一样司空见惯了(加个鸡蛋貌似也不错)。 \r\n      有时会出现另外的错误,形如:\r\n      An error occurred on the server when processing the URL. Please contact the system administrator. \r\n      恭喜你,你引发了一个Error,至于这个Error是什么,我也不知道。\r\n      解决方案:\r\n      打开IIS7的ASP设置的“调试属性”选项,“将错误发送到浏览器”设为True,然后点右边的应用即可。 \r\n      解决了该错误后,再次恭喜你,你有机会遇到第一个Error了。 \r\n      第一个问题出现的情况只有两种,这里直接说权限的问题,首先按照网上能广泛找到的,设置父路径,然后再给win7安装目录C:windowsServiceProfilesNetworkServiceAppDataLocalTemp目录添加一个\"Autheticated Users\"的读写或完全控制权限。\r\n      到这里有很多人依然无法连接Access的数据库,这里是由于在NTFS分区下另需配置权限,如下:\r\n      文件夹选项->查看把文件的简单共享去掉 (2K/XP)\r\n      右击数据库目录, 在安全选项卡里, 加上IUSR_XX (XX为你的机器名) 的可修改权限. (也可直接加入 guests 组或 everyone 修改权限. 不推荐)\r\n      给 \"系统盘:windowstemp\" 文件夹加上everyone的完全控制权限. (2003)\r\n      Provider 错误 \'80004005\'\r\n      未指定的错误\r\n      将\r\n      Set conn=Server.CreateObject(\"ADODB.CONNECTION\")\r\n      conn.open \"driver={microsoft access driver (*.mdb)};dbq=\"&server.mappath(\"example.mdb\")\r\n      第二行改写为\r\n      conn = \"Provider=Microsoft.Jet.OLEDB.4.0;DataSource=\"&Server.MapPath(\"example.mdb\")\r\n
\r\n
很显然这里我们采用了另一种方式避过了这个问题。一劳永逸的解决方案是:\r\nWin + Rregsvr32 jscript.dll (修复Java动态链接库)\r\nWin + Rregsvr32 vbscript.dll (修复VB动态链接库)\r\nWin + Riisreset (重启IIS)\r\nOK,现在我们终于可以开始 DoubleA(ASP + Access)了。
\r\n ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2984, 'win7-configure-php5-and-apache2-2', 'Win7下配置PHP5和Apache2.2', '2012-03-25 04:21:03', '2019-03-25 21:29:22', '第一、安装并配置APACHE(以我的为例,安装到E:Program FilesApache Software FoundationApache2.2)\r\n1、安装时默认安装,Network Domain, Server Name 我填写我的计算机名,Administrator\'s Email Address区域填你的邮件地址\r\n2、安装完后在安装目录下有个conf文件夹,打开httpd.conf文件进行配置\r\n·找到 DocumentRoot ,将其设置为你所要存放php, htm等网页文件的文件夹,如 \"E:Program FilesApache Software FoundationApache2.2htdocs\";\r\n·找到 DirectoryIndex ,在index.html后添加index.php, index.htm等,以单个空格将其分开;\r\n·重启Apache,用http://localhosthttp://127.0.0.1http://yourcompanyname测试是否成功。成功的话屏幕会有个It works!\r\n\r\n第二、安装配置PHP(解压PHP压缩包到d:php)\r\n1、将php.ini-recommended文件重命名为php.ini并将其剪到系统所在目录下(如放在2000/NT的WINNT/system32, XP的Windows/system32目录下),\r\n2、将extension_dir 改为php/ext所在目录,如 \"d:phpext\";\r\n3、将doc_root 改为第一步中的同样目录,如 \"E:Program FilesApache Software FoundationApache2.2htdocs\";\r\n4、找到 ;session.save_path = \"/tmp\" ,将\';\'去掉,设置你保存session的目录,如session.save_path = \"D:/php/session_temp\";\r\n5、然后把下面几句前面的分号去掉,以更好支持Mysql and PHPmyadmin\r\nextension=php_mbstring.dll\r\nextension=php_gd2.dll\r\nextension=php_mysql.dll\r\n\r\n第三、PHP+APACHE\r\n1、允许Apache将PHP程序作为模块来运行:\r\n打开httpd.conf,添加下面内容(位置任意):\r\nLoadModule php5_module \"d:/php/php5apache2_2.dll\"(特别注意这一条,很多地方是调用php5apache2.dll,这样在运行PHP代码时会提示httpd.exe应用程序错误)\r\nAddType application/x-httpd-php .php\r\nAddType application/x-httpd-php .htm\r\n(.htm, .php为可执行php语言的扩展名,也可加html, php3, php4,甚至txt)\r\n(以下两步可以不需要)\r\n2、如果你出于某种原因而需要在CGI模式中运行PHP程序(使用Php.exe),\r\n请将上面这一行变成注释(各行头加#即可),添加下面这些行:\r\n#     ScriptAlias /php/ \"d:/php/\"\r\n# AddType application/x-httpd-php .php\r\n#Action application/x-httpd-php \"/php/php-cgi.exe\"\r\n3、现在apache 2 支持HTML而不支持PHP,先把下面几句加到d:apache2confhttpd.conf去:\r\n# ScriptAlias /php/ \"d:/php/\"\r\n# AddType application/x-httpd-php .php\r\n#Action application/x-httpd-php \"/php/php-cgi.exe\"\r\n\r\n第四、重启服务\r\n1、在d:PHP里找到php5ts.dll,libmysql.dll将其复制到c:winntsystem32下(winNT/2000的机器),而winXP/2003是复制到c:windowssystem32下\r\n2、测试Apache与php是否连接成功:\r\n启动start apache服务或者正在运行的就重新启动restart apache\r\n3、在Web根目录下新建test.php(即E:Program FilesApache Software FoundationApache2.2htdocs目下)\r\n<html>\r\n<head><title>test</title></head>\r\n<body>\r\n<?php\r\nphpinfo();\r\n?>\r\n</body>\r\n</html>\r\n\r\n4、运行http://localhost/test.php\r\n如果成功,则应该看到一个含有PHP徽标的网页,其中包含大量设置和其他信息\r\n那么恭喜你!\r\n\r\n备注:\r\n如果不能运行,使用传统的模块化方法安装PHP5.1.* + apache 2.2.2 后不能启动,\r\n\r\n提示:\r\n\"Cannot load D:/php/php5apache2.dll into server: The specified module could not be found.\"\r\n\r\n原因:\r\n\r\nPHP压缩包里的php5apache2.dll只适用于apache2.0.*,是否把php5apache2.dll改为php5apache2_2.dll即第三步的第1小步\r\n另外的解决方法:\r\n\r\n下载(http://www.phpv.net/php5apache2.dll-php5.1.x.rar) 并解压.共有三个文件.\r\nvcredist_x86.exe\r\nphp5apache2.dll\r\nhttpd.exe.manifest\r\n1.将 php5apache2.dll 覆盖掉你原来PHP目录下的 php5apache2.dll 文件.\r\n2.将 httpd.exe.manifest 文件复制到你的apache安装目录下的bin文件夹下.\r\n3.双击运行vcredist_x86.exe安装.\r\n完成!去重启你的apache试试吧.', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2985, '53-hero-hero-killed-about-1-bao-si', '英雄杀53位英雄讲解1:褒姒', '2012-03-22 03:52:09', '2019-12-02 22:16:32', '
\r\n

\"\"\r\n

\r\n

褒姒 臣 三血\r\n

\r\n技能:烽火 出牌时,你可以选择弃掉一张装备区的牌,视为出一张【烽火狼烟】。\r\n\r\n技能:治愈 出牌时,你可以弃掉任意两张手牌,然后指定一个血量不满的男性角色,你和他可以各恢复1点血。每回合限用一次。\r\n\r\n主要语言:哏! 补充一下吧!\r\n\r\n人物介绍:褒姒,周幽王姬宫涅的王后,褒姒原是一名弃婴,被一对做小买卖的夫妻收养,在褒国(今陕西省汉中西北)长大,公元前七七九年(周幽王三年),周幽王征伐有褒国,褒人献出美女褒姒乞降,幽王爱如掌上明珠,立为妃,宠冠周王宫,翌年,褒姒生子伯服(一作伯般),幽王对她更加宠爱,竟废去王后申氏和太子宜臼,册立褒姒为王后,立伯服为太子,周太史伯阳叹气道:“周王室已面临大祸,这是不可避免的了。”褒姒因为过不惯宫中生活,加之养父被太子宜臼所杀,心中忧恨,平时很少露出笑容,偶露笑容,更加艳丽迷人,周幽王发出重赏,谁能诱发褒姒一笑,赏以千金,虢国石父献出“烽火戏诸侯”的奇计,最终导致幽王被杀,褒姒被掳。\r\n\r\n特色:对于这个角色来说,装备牌就是灵魂,但是由于嘲讽率极高,所以往往会打酱油!\r\n\r\n3V3休闲:出现的几率虽然没有竞技的几率大,但是如果看见秦始皇、虞姬、李师师、鲁班这些强助攻的人物。往往会选择褒姒出现在场上,褒姒最喜欢的就是虞姬和秦始皇这样的组合,她每放一次火,虞姬掉血主公给牌,秦始皇掉血集权。这样的阵容出现在场会让对手不寒而栗,往往不等到开战就会胆寒七分!如果出现没有上述这些人物,褒姒需要蓄暴,顾名思义,就是有装备不出,赞起来,但是由于嘲讽率极高,所以肯定是被先杀的对象,请慎重考虑 ,以免连累队友!\r\n\r\n3v3竞技:作为四神一妖的其中之一,褒姒在竞技的实力是可想而知的!如果对面没有慕容,\r\n那么褒姒作为主将的几率是很大的。在这里褒姒就不怎么喜欢秦始皇了,配合对象就多的多了!但是褒姒还是喜欢虞姬、李师师!放火李师师和虞姬无限主公,到最后收她们的人头拿牌,极大几率会秒掉全场,从而胜利!但是如果对面有慕容的画就不要去选择褒姒了,这个我就不多说了,你懂得!如果没有很好的助攻人物,依然是蓄暴,最后你的副将都是3血的人物,如果是4血的要看是什么武将在随机而动!拥有的治愈神技也是可以帮你维持一段时间的良好佳药!\r\n\r\n5-8人场:八人场褒姒做主公的几率不大,忠臣也不会狠大,因为在多人场,褒姒的嘲讽率大大提高了100%!也就是说,肯定是被先杀的角色,除廉颇以外!所以褒姒要看时机在放火,在能收到人头的情况下可以选择放火,如果收不到往往会被忠臣收走,那么就可能被翻盘!所以一定要做好充足的准备,在这里还是可以说一点,那就是蓄暴!在多人场能看到过褒姒小内收全场的,但是不要以为烽火就可以解决问题,有时候给队友治愈一下也是可以增加你的爆发力的!如果作为主或忠,就要先看清反贼和忠臣的时候在反火,以免伤到自己人!那样可能会被骂,拖累队友!\r\n\r\n单挑:褒姒的单挑能力不大,但是一回合开始回血的技能也是让队友头疼!\r\n\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2986, 'clearlist-linear-tables-and-destroy-differences', '线性表中ClearList和Destroy的区别', '2012-03-19 04:40:26', '2019-03-25 21:29:22', '
        ClearList只是把线性表中原来存储元素的空间中存的那些元素都清除了,类似于把原线性表改成一个空的线性表,但这个线性表是确实存在的。\r\n而Destroy是把整个线性表占的空间都释放了,这个线性表结构都不存在了,下次想做一个线性表只能重新初始化。\r\n下面是它们的粗略算法:\r\n顺序表的:\r\n销毁线性表L\r\nvoid DestroyList(SqList*L)\r\n{\r\nif (L->elem) free(L->elem);      //释放线性表占据的所有存储空间\r\n}\r\n清空线性表L\r\nvoid ClearList(SqList*L)\r\n{\r\nL->length=0;                //将线性表的长度置为0\r\n}\r\n链表的:\r\n销毁链表L\r\nvoid DestoryList(LinkList *L)\r\n{\r\nNODE *p;\r\nwhile (L->head){             //依次删除链表中的所有结点\r\np=L->head; L->head=L->head->next;\r\nfree(p);\r\n}\r\n}\r\n清空链表L\r\nvoid ClearList(LinkList *L)\r\n{\r\nNODE *p;\r\nwhile (L->head->next){\r\np=L->head->next;      //p指向链表中头结点后面的第一个结点\r\nL->head->next=p->next;     //删除p结点\r\nfree(p);     //释放p结点占据的存储空间\r\n}\r\n}
\r\n ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2987, 'struts2-is-installed-in-the-netbeans-plugin', '在NetBeans中安装struts2插件', '2012-03-17 03:01:05', '2019-03-25 21:29:22', '

对于NetBeans6.9.1来说,其完整版安装只包含了struts1,并且在其“工具”—》“插件”—》“可用插件”中没有struts2,本文将讨论如何在NetBeans中安装struts2插件。

\r\n

首先,我们必须获得NetBeans对应版本的struts2插件,我们可以在NetBeans官网(http://plugins.netbeans.org/)插件部分寻找我们需要的插件。

\r\n

 

\r\n

 

\r\n

\"在NetBeans中安装struts2插件图片1\"

\r\nNetBeans6.9.1对应的struts2插件为:nbstruts2support-nb6.9.1.ziphttp://plugins.netbeans.org/plugin/23467/netbeans-struts2-support)。将下载文件解压后,我们将会得到如下图上个文件:\r\n\r\n \r\n

\"在NetBeans中安装struts2插件图片2\"

\r\n

然后启动NetBeans,一次点击“工具”—》“插件”—》“已下载”—》“添加插件”,重复三次选中以上三个文件,

\r\n \r\n

<!--[endif]-->

\r\n

 

\r\n

\"在NetBeans中安装struts2插件图片3\"

\r\n \r\n

接着点击安装,出现如下图示:

\r\n

 

\r\n

 

\r\n

\"在NetBeans中安装struts2插件图片4\"

\r\n安装完成后,会提示重启。重启NetBeans后,新建项目,在选择框架时,会出现如图示:\r\n\r\n \r\n\r\n \r\n

 

\r\n

\"在NetBeans中安装struts2插件图片5\"

\r\n表示插件安装成功。\r\n\r\n \r\n

最后,创建一个默认struts2项目,并进行测试,发现运行正常,表示struts2安装成功,大功告成。

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2988, 'scanf-function-in-c-language-details', 'C语言中scanf函数的详解', '2012-03-13 20:45:43', '2019-03-25 21:29:22', '
    scanf()函数是所有C语言学习者在学习C语言过程中所遇到的第二个函数(第一个函数是printf(),Brian W.Kerninghan & Dennis M.Ritchie的“hello,world”程序基本上是所有的C语言学习者第一个范例),所以scanf()函数应当是C学习者能熟练运用的一个函数,但有很多初学者对此函数不能很好的运用,在实际编程中错误使用scanf()函数,导至程序产生某种错误不能正常运行,以至产生“scanf()函数有BUG”,“scanf()函数无用论”等等错误观点。\r\n本文结合笔者在编程实践中及论坛上网友所遇到的问题作一释疑,但笔者水平有限(菜鸟级),难免有谬误之处,还望达人指点一二。(Email:cyutyw@126.com)\r\n本文分上,下两篇讲述了C语言中的scanf()函数的用法,重点阐述使用scanf()函数过程中出现的常见错误及对策。当然,文中某些解决方法,均可以采用其他函数和方法来更好地解决,但本文仅限讨论scanf()函数本身。\r\n上篇,详细介绍了scanf()函数控制串的构成。下篇,用实际例程介绍scanf()函数控制串运用出现的常见错误及对策技巧。\r\n
\r\n
 scanf()函数的控制串
\r\n
函数名: scanf\r\n功 能: 执行格式化输入\r\n用 法: int scanf(char *format[,argument,...]);
\r\n
scanf()函数是通用终端格式化输入函数,它从标准输入设备(键盘) 读取输入的信息。可以读入任何固有类型的数据并自动把数值变换成适当的机内格式。
\r\n
其调用格式为: scanf(\"<格式化字符串>\",<地址表>);
\r\n
scanf()函数返回成功赋值的数据项数,出错时则返回EOF。
\r\n
其控制串由三类字符构成:
\r\n
1。格式化说明符;\r\n2。空白符;\r\n3。非空白符;
\r\n
\r\n(A) 格式化说明符
\r\n
\r\n格式字符 说明
\r\n
%a 读入一个浮点值(仅C99有效)\r\n%A 同上\r\n%c 读入一个字符\r\n%d 读入十进制整数\r\n%i 读入十进制,八进制,十六进制整数\r\n%o 读入八进制整数\r\n%x 读入十六进制整数\r\n%X 同上\r\n%c 读入一个字符\r\n%s 读入一个字符串\r\n%f 读入一个浮点数\r\n%F 同上\r\n%e 同上\r\n%E 同上\r\n%g 同上\r\n%G 同上\r\n%p 读入一个指针\r\n%u 读入一个无符号十进制整数\r\n%n 至此已读入值的等价字符数\r\n%[] 扫描字符集合\r\n%% 读%符号附加格式说明字符表\r\n\r\n
\r\n
修饰符 说明
\r\n
L/l 长度修饰符 输入\"长\"数据\r\nh 长度修饰符 输入\"短\"数据\r\nW 整型常数 指定输入数据所占宽度\r\n* 星号 空读一个数据\r\nhh,ll同上h,l但仅对C99有效。
\r\n
\r\n(B) 空白字符
\r\n
空白字符会使scanf()函数在读操作中略去输入中的一个或多个空白字符,空白符可以是space,tab,newline等等,直到第一个非空白符出现为止。
\r\n
(C) 非空白字符
\r\n
一个非空白字符会使scanf()函数在读入时剔除掉与这个非空白字符相同的字符。
\r\n
\r\n注:scanf()控制串知识就介绍到这里(应该比较齐全了^_^),如有遗漏下次补上。下面将结合实际例程,一一阐述.\r\n
\r\n
scanf()函数的控制串的使用
\r\n
例1.\r\n
 
\r\n
\r\n
#include \"stdio.h\"\r\nint main(void)\r\n{\r\nint a,b,c;scanf(\"%d%d%d\",&a,&b,&c);\r\nprintf(\"%d,%d,%d/n\",a,b,c);\r\n\r\n
\r\n
return 0;\r\n}
\r\n
运行时按如下方式输入三个值:
\r\n
3□4□5 ↙(输入a,b,c的值)
\r\n
3,4,5 (printf输出的a,b,c的值)
\r\n
(1) &a、&b、&c中的&是地址运算符,分别获得这三个变量的内存地址。\r\n(2) \"%d%d%d\"是按十进值格式输入三个数值。输入时,在两个数据之间可以用一个或多个空格、tab键、回车键分隔。\r\n以下是合法输入方式:\r\n① 3□□4□□□□5↙\r\n② 3↙\r\n4□5↙\r\n③ 3(tab键)4↙\r\n5↙
\r\n
\r\n例2.
\r\n
#include \"stdio.h\"\r\nint main(void)\r\n{\r\nint a,b,c;
\r\n
scanf(\"%d,%d,%d\",&a,&b,&c);\r\nprintf(\"%d,%d,%d/n\",a,b,c);
\r\n
return 0;\r\n}
\r\n
运行时按如下方式输入三个值:
\r\n
3,4,5 ↙(输入a,b,c的值)
\r\n
或者
\r\n
3,□4,□5 ↙(输入a,b,c的值)
\r\n
3,□□□4,□5 ↙(输入a,b,c的值)\r\n......\r\n都是合法的,但是\",\"一定要跟在数字后面,如:\r\n3□,4,□5 ↙就非法了,程序出错。(解决方法与原因后面讲)
\r\n
再如:
\r\n
1、sacnf()中的变量必须使用地址。
\r\n
   int a, b;\r\nscanf(\"%d%d\",a,b); //错误\r\nscanf(\"%d%d\",&a,&b);
\r\n
2、scanf()的格式控制串可以使用其它非空白字符,但在输入时必须输入这些字符。
\r\n
例:\r\nscanf(\"%d,%d\",&a,&b);\r\n输入: 3,4 ↙(逗号与\"%d,%d\"中的逗号对应)\r\nscanf(\"a=%d,b=%d\",&a,&b);\r\n输入: a=3,b=4 ↙(\"a=\",\"b=\",逗号与\"%d,%d\"中的\"a=\",\"b=\"及逗号对应)
\r\n
\r\n3、在用\"%c\"输入时,空格和“转义字符”均作为有效字符。
\r\n
例:\r\nscanf(\"%c%c%c\",&c1,&c2,&c3);\r\n输入:a□b□c↙\r\n结果:a→c1,□→c2,b→c3 (其余被丢弃)
\r\n
\r\nscanf()函数接收输入数据时,遇以下情况结束一个数据的输入:(不是结束该scanf函数,scanf函数仅在每一个数据域均有数据,并按回车后结束)。\r\n① 遇空格、“回车”、“跳格”键。\r\n② 遇宽度结束。\r\n③ 遇非法输入。
\r\n
\r\n上篇就写到这里吧,第三小节的例程\"抄\"自网上的一个教程(原因有二:一,可以少打不少字。二,□↙我不知道怎么打。^_^),并删去其中的错误之处.这里也顺便提醒本文读者一句:凡事要亲力而为,即使是经典的书籍也不免有疏漏之处,所以,用编译器说话是最可靠的,是对是错请编译器告诉你。
\r\n
\r\n在上篇我已经表达了两个观点,这里再重申一次:1。本文仅对scanf()函数控制串运用进行探讨,本文所有例程并不构成编程建议。2。凡事要亲力而为,不同平台不同编译器,可能会有不同结果。本文所有例程均在WIN-TC+windows Me下调试。
\r\n
 
\r\n
问题二:scanf()函数不能正确接受有空格的字符串?如: I love you!
\r\n
\r\n#include <stdio.h>\r\nint main()\r\n{\r\nchar str[80];scanf(\"%s\",str);\r\nprintf(\"%s\",str);\r\n\r\n
\r\n
return 0;\r\n}
\r\n
输入:I live you!\r\n输出:I
\r\n
scanf()函数接收输入数据时,遇以下情况结束一个数据的输入:(不是结束该scanf函数,scanf函数仅在每一个数据域均有数据,并按回车后结束)。\r\n① 遇空格、“回车”、“跳格”键。\r\n② 遇宽度结束。\r\n③ 遇非法输入。
\r\n
所以,上述程序并不能达到预期目的,scanf()扫描到\"I\"后面的空格就认为对str的赋值结束,并忽略后面的\"love you!\".这里要注意是\"love you!\"还在键盘缓冲区(关于这个问题,网上我所见的说法都是如此,但是,我经过调试发现,其实这时缓冲区字符串首尾指针已经相等了,也就是说缓冲区清空了,scanf()函数应该只是扫描stdin流,这个残存信息是在stdin中)。我们改动一下上面的程序来验证一下:
\r\n
#include <stdio.h>\r\nint main()\r\n{\r\nchar str[80];\r\nchar str1[80];\r\nchar str2[80];scanf(\"%s\",str);/*此处输入:I love you! */\r\nprintf(\"%s\",str);\r\nsleep(5);/*这里等待5秒,告诉你程序运行到什么地方*/\r\nscanf(\"%s\",str1);/*这两句无需你再输入,是对键盘盘缓冲区再扫描 */\r\nscanf(\"%s\",str2);/*这两句无需你再输入,是对键盘盘缓冲区再扫描 */\r\nprintf(\"/n%s\",str1);\r\nprintf(\"/n%s\",str2);\r\nreturn 0;\r\n}\r\n\r\n
\r\n
输入:I love you!\r\n输出:I\r\nlove\r\nyou!
\r\n
好了,原因知道了,那么scanf()函数能不能完成这个任务?回答是:能!别忘了scanf()函数还有一个 %[] 格式控制符(如果对%[]不了解的请查看本文的上篇),请看下面的程序:
\r\n
#include \"stdio.h\"\r\nint main()\r\n{\r\nchar string[50];/*scanf(\"%s\",string);不能接收空格符*/\r\nscanf(\"%[^/n]\",string);\r\nprintf(\"%s/n\",string);\r\nreturn 0;\r\n}\r\n\r\n
\r\n
问题三:键盘缓冲区残余信息问题
\r\n
\r\n#include <stdio.h>\r\nint main()\r\n{\r\nint a;\r\nchar c;
\r\n
do\r\n{\r\nscanf(\"%d\",&a);\r\nscanf(\"%c\",&c);\r\nprintf(\"a=%d c=%c/n\",a,c);\r\n/*printf(\"c=%d/n\",c);*/\r\n}while(c!=\'N\');\r\n}
\r\n
scanf(\"%c\",&c);这句不能正常接收字符,什么原因呢?我们用printf(\"c=%d/n\",c);将C用int表示出来,启用printf(\"c=%d/n\",c);这一句,看看scanf()函数赋给C到底是什么,结果是 c=10 ,ASCII值为10是什么?换行即/n.对了,我们每击打一下\"Enter\"键,向键盘缓冲区发去一个“回车”(/r),一个“换行\"(/n),在这里/r被scanf()函数处理掉了(姑且这么认为吧^_^),而/n被scanf()函数“错误”地赋给了c.
\r\n
解决办法:可以在两个scanf()函数之后加个fflush(stdin);,还有加getch(); getchar();也可以,但是要视具体scanf()语句加那个,这里就不分析了,读者自己去摸索吧。但是加fflush(stdin);不管什么情况都可行。
\r\n
函数名: fflush\r\n功 能: 清除一个流\r\n用 法: int fflush(FILE *stream);
\r\n
#include <stdio.h>\r\nint main()\r\n{\r\nint a;\r\nchar c;
\r\n
do\r\n{\r\nscanf(\"%d\",&a);\r\nfflush(stdin);\r\nscanf(\"%c\",&c);\r\nfflush(stdin);\r\nprintf(\"a=%d c=%c/n\",a,c);
\r\n
}while(c!=\'N\');\r\n}
\r\n
这里再给一个用“空格符”来处理缓冲区残余信息的示例:
\r\n
运行出错的程序:
\r\n
#include <stdio.h>\r\nint main()\r\n{\r\nint i;\r\nchar j;\r\nfor(i = 0;i < 10;i++)\r\n{\r\nscanf(\"%c\",&j);/*这里%前没有空格*/\r\n}\r\n}
\r\n
使用了空格控制符后:
\r\n
#include <stdio.h>\r\nint main()\r\n{\r\nint i;\r\nchar j;\r\nfor(i = 0;i < 10;i++)\r\n{\r\nscanf(\" %c\",&j);/*注意这里%前有个空格*/\r\n}\r\n}
\r\n
可以运行看看两个程序有什么不同。
\r\n
问题四 如何处理scanf()函数误输入造成程序死锁或出错?
\r\n
#include <stdio.h>\r\nint main()\r\n{\r\nint a,b,c; /*计算a+b*/
\r\n
scanf(\"%d,%d\",&a,&b);\r\nc=a+b;\r\nprintf(\"%d+%d=%d\",a,b,c);\r\n}
\r\n
如上程序,如果正确输入a,b的值,那么没什么问题,但是,你不能保证使用者每一次都能正确输入,一旦输入了错误的类型,你的程序不是死锁,就是得到一个错误的结果,呵呵,这可能所有人都遇到过的问题吧?
\r\n
解决方法:scanf()函数执行成功时的返回值是成功读取的变量数,也就是说,你这个scanf()函数有几个变量,如果scanf()函数全部正常读取,它就返回几。但这里还要注意另一个问题,如果输入了非法数据,键盘缓冲区就可能还个有残余信息问题。
\r\n
正确的例程:
\r\n
#include <stdio.h>\r\nint main()\r\n{\r\nint a,b,c; /*计算a+b*/
\r\n
while(scanf(\"%d,%d\",&a,&b)!=2)fflush(stdin);\r\nc=a+b;\r\nprintf(\"%d+%d=%d\",a,b,c);\r\n}
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2989, 'use-stacks-to-write-recursive-and-non-recursive-fibonacci-programs', '用栈写出Fibonacci的递归和不递归程序', '2012-03-12 06:50:48', '2019-03-25 21:29:22', '方法函数:\r\n递归: \r\n
int fib(int n)\r\n{\r\nif( n<=1 ) return n;\r\nelse return fib(n-1)+fib(n-2);\r\n}
\r\n非递归: \r\n
int fib(int n)\r\n{\r\nint f1=0,f2=1,i,temp;\r\nfor(i=0;i<n;++i)\r\n{\r\ntemp=f1; f1=f2; f2=temp+f1;\r\n}\r\nreturn f1;\r\n}\r\n
\r\n
\r\n测试程序:
\r\n
#include <iostream>\r\nusing namespace std;int fib(int n)\r\n{\r\nint f1=0,f2=1,i,temp;\r\nfor(i=0;i<n;++i)\r\n{\r\ntemp=f1;\r\nf1=f2;\r\nf2=temp+f1;\r\n}\r\nreturn f1;\r\n}\r\n\r\nint main()\r\n{\r\nint n=0;\r\nint t=0;\r\ncout<<\"请输入n\"<<endl;\r\ncin>>n;\r\nt=fib(n);\r\ncout<<t;\r\nreturn 0;\r\n}\r\n运行演示:\"\"\r\n\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2990, 'set-of-random-variables-x-obey-exponential-distribution-with-parameter-is-1-to-2-proof-y1-e-%cb%86-2x-in-the-interval-01-the-uniform-distribution-on', '设随机变量x服从参数为1/2的指数分布,证明:Y=1-eˆ(-2x)在区间(0,1)上的均匀分布。', '2012-03-11 21:50:29', '2019-03-25 21:29:22', '题目:设随机变量x服从参数为1/2的指数分布,证明:Y=1-eˆ(-2x)在区间(0,1)上的均匀分布。\r\n\r\n答案:利用分布函数法,假设Y的分布函数为F(y),则根据分布函数的定义可知\r\nF(y)=P(Y<=y)=P(1-eˆ(-2X)<=y),由于x服从参数为1/2的指数分布,因此X可能的取值范围应该是0到正无穷。因此1-eˆ(-2X)可能的取值范围应该是[0,1]。可知当y<0时,P(1-eˆ(-2X)<=y)=0,当y>=1时,P(1-eˆ(-2X)<=y)=1。当0<=y<1时,P(1-eˆ(-2X)<=y)=P(X<=1/2ln(1-y))=y。\r\n可知Y的分布函数即为区间(0,1)上的均匀分布的分布函数,也即Y服从均匀分布。\r\n\r\n总结:分布函数法是求解随机变量函数分布的主要方法,需要深入理解分布函数的定义。事实上,本题的结论也可以看做一个定理的应用:设随机变量X的分布函数为F(x),则随机变量Y=F(X)服从区间(0,1)上的均匀分布。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2992, 'easy-to-remember-password-for-yourself-did-you-do-it', '给自己起个易记的密码,你做到了吗?', '2012-03-06 07:23:21', '2019-03-25 21:29:22', '
译者桃源过客 微博http://weibo.com/tyouwei
\r\n
      密码是做很多事的关键。例如你的邮件,你的facebook首页,或着你的银行账户。你知道有些人仍然在使用诸如“password”“123456”此类的密码吗?\r\n\"\"\r\n      不用说,在你的所有网络账户上使用同一个简单密码是很危险的。设想一下,如果黑客攻击了那个密码怎么办?你必须为这些解密高手创建独特、难以破解的密码。因此,你知道怎样创建一个好的密码吗?你怎么记住多个密码而不是一个呢?下面有一些方法和技巧为你的所有网络账户创建个人的强密码。\r\n你知道安全密码的字符吗?他们是不能再字典中查到的。他们拥有特殊的字符和数字。它包含混合大小写的字母。他至少拥有10个字母。它不能简单的依靠用户信息(生日、邮政编码、省份证等等)。创建一个容易记住的密码要根据密码来定。你可以使用一些技巧来创建一个你不容易忘记的好密码。下面有一些建议。\r\n1.随机代替字母编号,例如你可以将flirt替换成fl1r7;\r\n      2.选择一个句子,记你的密码,用每一个单词的第一个字母来代替,例如,你可以将Everything I Do I Do It For Yo替换成EIDIDIFY;\r\n3.将一个单词反向拼写,例如将neighborhood替换成doohrobhgien;这些例子并不是很安全,尽管这些单词都不能再字典中查到,但其他字母似的它们也不能成为一个安全的密码。试着找一个组合,让它包含你所有的特点,例如,我打算用这密码是“E1d_1D ! 4 Y:)”。\r\n注意我的基本密码符合所有上述标准。它不能被在词典中查到,它包含特殊字符,一个混合的大小写字母,是11个字符长,不能基于我个人信息猜到(除非你怀疑我喜欢布Bryan Adams)。\r\n有创意一点,超越常规思维。计算机的速度比你能够识别的速度,比任何人的大脑的速度都快得多,但有一件事不能做的就是创新。对黑客工具来说,这是你最大的优势!正如你看见的,在我的密码中,我换一些字母编号或特殊字符。然而,我没有使用一个硬套规则。我把“I”换成“1”,而不是“!”。\r\n更换使用字符的规则,例如,总是将“a”换成“@”,这会削弱你的密码。以下是一些方法能使黑客更难破解密码:不使用普通的替代字符,例如,“@”换成“A/a”。当你的密码有重复的字母时,混合它们。例句8替换成“B / b”。\r\n想一个词,并用键盘错误的敲下来。记住,你可以切换键盘类型。你的键盘上挑一个模式,交替并使用SHIFT键,例如Xdr %6tfCvgz测试你的密码,你确定你的密码确实是安全的吗?密码测量会揭示你的密码的长度。然而,如果你的密码太长了,即太安全了,这个测试会失败。\r\n每个帐户创造单独的密码的基础密码,一旦你有了一个密码,你可以用它来为你的每一个在线帐户创建密码。简单地增加前三个字母,例如。”E1d_1D!4Y:)GMa\"为您GMail帐户或“E1d_1D ! 4 Y:)eBa“。要想超级安全,你应该有两个基本的密码。他们将被用来将重要和不是那么重要的账户分开。你会使用一个密码,网站上有个人信息或信用卡详细资料,或GMail付款。第二个密码将被用于论坛和类似的网站,如果入侵不会具有巨大的危害性。然而,密码应该同样很强。\r\n定期更新密码这是最困难的部分。维持一个强大安全的密码,你需要每隔几周或几个月更新您的密码。越是经常越好。你可以用很多不同的方式做这个。这里有一些建议来保持简单。改变你的基本密码:使用特殊字符替换。反向使用大小写字母。◦\r\n输入密码与转移锁打开。改变整个密码:改变你确定的帐号,您正在使用,例如使用三个而不是前三个字母(GMa将成为ail或eBa将成为Bay)。改变识别账户的字母的位置,如将他们放在你的基本密码的前面。\r\n为你最后一次改变密码添加日期并记在你的日历中。换句话说,使用你的优势:有创造力,超越寻常思维。如果你觉得“容易记住“密码不安全,您可以使用斯蒂芬的文章自由密码发生器产生的不可攻击的密码。你还有其他方法来创造一个强大的密码吗?      以下是英文版原文(原文地址:http://www.makeuseof.com/tag/create-strong-password-forget/):\r\n\r\nHow To Create A Good Password That You Will Not Forget\r\n\r\n
\r\nFebruary 21, 2010    By Tina Sieber\r\n\r\nPasswords can be a key to many things, for example your emails, your Facebook profile, or your bank account. Did you know that some people still use passwords like “password” or “123456″?\r\n\r\nNeedless to say, it’s dangerous to use one and the same simple password for all of your online accounts. Imagine a hacker cracked that one password? To be safe, you should create unique and difficult to crack passwords. So do you know how to create a good password? And how can you remember more than one of them? Here are some tips and tricks to maintain individual strong passwords for all of your online accounts.\r\n\r\nKnow The Characteristics Of A Safe Password ?it cannot be found in a dictionary. it contains special characters and numbers. it contains a mix of upper and lower case letters. it has a minimum length of 10 characters. it cannot be guessed easily based on user information (birthdate, postal code, phone number etc.) Create An Easy To Remember Base Password You can use several techniques how to create a good password that you will not forget.\r\nHere are some suggestions.\r\n\r\nRandomly replace letters with numbers, e.g. flirt becomes fl1r7.\r\n\r\nPick a sentence, i.e. your passphrase, and reduce it to first letters of each word only, e.g. “Everything I Do I Do It For You” becomes EIDIDIFY.\r\n\r\nTake a word and reverse spell it, e.g. neighborhood becomes doohrobhgien. These examples are not very safe. While none of the words can be found in a dictionary, they are still failing other characteristics of a safe password. Try to find a combination that allows you to incorporate all characteristics. The base password I’m going to use for this password is “E1d_1D!4Y:)“.\r\n\r\nNote that my base password meets all of the above criteria. It cannot be found in a dictionary, it contains special characters, a mix of upper and lower case letters, it is 11 characters long, and cannot be guessed based on my personal information (unless you suspect that I like Bryan Adams).\r\n\r\nBe Creative & Think Out Of The Box! A computer may calculate faster than you can recognize patterns a lot quicker than any human brain, but one thing it cannot do is be creative. That is your great advantage over hacker tools! As you see, in my password I replaced some letters with numbers or special characters. However, I didn’t use a stiff set of rules. I replaced the “I” with a “1″ or a “!”.\r\n\r\nUsing rules for replacing characters, i.e. always replacing an “a” with the “@” symbol will weaken your password. Here are some ideas how you can make it even harder for a hacker to crack your password: Don’t use common substitutions, e.g. @ for A/a. When you have recurring letters within your password, mix your substitutions, e.g. 8 or ( for B/b.\r\n\r\nHave a word and touch type it with your fingers in the etpmh (wrong) location. Keep in mind that you may switch keyboard types. Pick a pattern on your keyboard and type it with alternating use of the SHIFT key, e.g. Xdr%6tfCvgz/ Test Your Password Do you want to make sure your password is indeed safe? The Password Meter will reveal details about the strengths and weaknesses of your password. However, if your password is too long, i.e. too safe, this test will actually fail.\r\n\r\nCreate Individual Passwords For Every Account Once you have a strong base password, you can use it to create individual passwords for each of your online accounts. Simply add the first three letters of the service, e.g. “E1d_1D!4Y:)GMa” for your GMail account or “E1d_1D!4Y:)eBa” for eBay. Be Super Safe To be super safe, you should have TWO base passwords. They will be used to keep important and not so important accounts separate. You would use one password for sites which hold personal information or credit card details, such PayPal or GMail. The second password would be used for forums and similar sites that would not be of great harm if hacked. However, the passwords should be equally strong.\r\n\r\nUpdate Passwords Regularly This is the toughest part. To maintain safety with a strong password, you have to update your password every few weeks or months. The more often, the better. You can do this in several different ways. Here are some ideas that will keep it simple. Change your base password only: Change the special character substitutions you’re using. ◦Reverse use of upper and lower case letters.\r\n\r\nType the password with SHIFT lock turned on. Change entire password: ◦Change how you identify the account you’re using, e.g. use the last three rather than the first three letters (GMa would become ail or eBa would become Bay). Change the position of the letters identifying the account, e.g. put them to the front or in the middle of your base password.\r\n\r\nAdd the date of when you last changed the password at the back and mark it in your calendar. In other words, use your human advantage: be creative and think out of the box. If you don’t feel safe with “easy to remember” passwords, you will enjoy Stefan’s article on 5 Free Password Generators For Nearly Unhackable Passwords. Do you have any additional tips on how to create a strong password?', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2993, 'c-include-stdafx-h-details', 'C语言中#include "stdafx.h"详解', '2012-03-06 05:15:53', '2019-03-25 21:29:22', '        stdafx英文全称:Standard Application Framework Extensions。\r\n所谓头文件预编译,就是把一个工程(Project)中使用的一些MFC标准头文件(如Windows.H、Afxwin.H)预先编译,以后该工程编译时,不再编译这部分头文件,仅仅使用预编译的结果。这样可以加快编译速度,节省时间。\r\n预编译头文件通过编译stdafx.cpp生成,以工程名命名,由于预编译的头文件的后缀是“pch”,所以编译结果文件是projectname.pch。   编译器通过一个头文件stdafx.h来使用预编译头文件。stdafx.h这个头文件名是可以在project的编译设置里指定的。编译器认为,所有在指令#include \"stdafx.h\"前的代码都是预编译的,它跳过#include \"stdafx. h\"指令,使用projectname.pch编译这条指令之后的所有代码。\r\nafx曾经是微软一个专门的技术开发团队,而stdafx.h则是这个团队为了定义一些环境配置、参数设置等专门定义的。\r\n工作原理及作用 \r\nstdafx.h中没有函数库,只是定义了一些环境参数,使得编译出来的程序能在32位的操作系统环境下运行。\r\nWindows和MFC的include文件都非常大,即使有一个快速的处理程序,编译程序也要花费相当长的时间来完成工作。由于每个.CPP文件都包含相同的include文件,为每个.CPP文件都重复处理这些文件就显得很傻了。为避免这种浪费,AppWizard和VisualC++编译程序一起进行工作,如下所示:\r\n◎AppWizard建立了文件stdafx.h,该文件包含了所有当前工程文件需要的MFCinclude文件。且这一文件可以随被选择的选项而变化。   ◎AppWizard然后就建立stdafx.cpp。这个文件通常都是一样的。   ◎然后AppWizard就建立起工程文件,这样第一个被编译的文件就是stdafx.cpp。\r\n◎当VisualC++编译stdafx.cpp文件时,它将结果保存在一个名为stdafx.pch的文件里。(扩展名pch表示预编译头文件。)\r\n◎当VisualC++编译随后的每个.cpp文件时,它阅读并使用它刚生成的.pch文件。VisualC++不再分析Windowsinclude文件,除非你又编辑了stdafx.cpp或stdafx.h。\r\n这个技术很精巧,你不这么认为吗?(还要说一句,Microsoft并非是首先采用这种技术的公司,Borland才是。)在这个过程中你必须遵守以下规则:\r\n◎你编写的任何.cpp文件都必须首先包含stdafx.h。\r\n◎如果你有工程文件里的大多数.cpp文件需要.h文件,顺便将它们加在stdafx.h(后部)上,然后预编译stdafx.cpp。\r\n◎由于.pch文件具有大量的符号信息,它是你的工程文件里最大的文件。\r\n如果你的磁盘空间有限,你就希望能将这个你从没使用过的工程文件中的.pch文件删除。执行程序时并不需要它们,且随着工程文件的重新建立,它们也自动地重新建立。 编辑本段stdafx.h的作用\r\n当我们使用AppWizard来自动生成某些项目的时候,系统会自动把所需要include的头文件在stdafx.h中先include一下,这样,我们只需要直接include这个stdafx.h文件即可.因为同一个项目中的不同源文件CPP都包含相同的include文件,这样,为每个.CPP文件都重复include这些文件就显得很傻了。\r\n具体在stdafx.h中需要include什么头文件,取决于用户在AppWizard中的选择.\r\n比如:\r\n#include // MFC core and standard components\r\n#include // MFC extensions\r\n#include // MFC OLE classes\r\n#include // MFC OLE dialog classes\r\n#include // MFC Automation classes   ......\r\n等等,这样,就方便多了.所以,stdafx.h是自动生成的.这就使得用户在开发中不必在每一个cpp文件中都烦琐的include头文件了,而且,维护起来也方便.\r\n在生成stdafx.h头文件的同时,也生成了stdafx.cpp源文件,该源文件只包含#include \"stdafx.h\"语句,这是在编译过程中第一个被编译的文件,编译的结果保存在一个名为stdafx.pch的文件里。 (扩展名pch表示预编译头文件。)当Visual C++编译随后的每个.cpp文件时,它阅读并使用它刚生成的.pch文件。 Visual C++不再分析Windows include文件,除非用户又编缉了stdafx.cpp或stdafx.h。\r\n看了这样的讲解,我马上就实验了一下,自己新建立一个windows窗口项目,很快,就生成了stdafx.cpp和stdafx.h. 并且,在主源文件form1.cpp中,就include此头文件stdafx.h.\r\n以上情况,只在使用AppWizard来自动生成项目的时候,才出现.否则,就没有必要include此头文件stdafx.h了。\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2994, 'windows8-turned-out-three-major-functions-of-shock-attack', 'Windows8横空出世 三大功能震撼出击', '2012-03-05 05:00:22', '2019-03-25 21:29:22', '
\r\n

    译者:桃源过客 微博:http://weibo.com/tyouwei\r\n    Windows8是一个新的Windows。我们知道,它将要求Windows用户学习和其他电脑连接的新方式,但是还有比他更多的内容。在这个平台上,应用程序工作方式和电脑与其他电脑连接的方式新颖,不同,而且相当好。\r\nWindows8消费者预览版预装了一些应用程序,其中有一些可以在Windows store下载。微软提醒这些应用都是预览品,他们在巴塞罗那说:“现在还不是评估、列出、分类这些应用的最好时机。”但是提前了解他们是怎么工作,怎么彼此配合将会揭示很多关于Windows8的工作方式。\r\n预装的用户、信息和邮件应用特别展示了Windows8使用、开发、构建应用的新方式。大多数即时通信服务都有他们独自的联系人列表,这些列表只是用于私人发布即时信息。这和邮件应用不同。这些应用构建、管理这些列表,并且不得不提供一个UI来实现这个功能。\r\n信息应用非常简单,但他最基本的设计工作的很好。\r\n从技术上来讲,在Windows8中,并没有阻止拥有相同的应用发展风格,但提供的应用并没有那样工作。信息和邮件应用并没有他们独自的联系列表。取而代之的是,他们能召唤用户应用并从那里取得列表。\r\nWindows phone用户将会对用户应用的基本观念非常熟悉,但是他和Windows phone上的People pub应用是不同的,他聚合了大量的信息使之有整体的效果。\r\n联系有不同的来源分隔符:Windows Live/Hotmail, Twitter, Exchange, Facebook, LinkedIn, MySpace (honestly!), 和Google. 你可以进入每个应用了解更多-他会暂显示最近的社交网络更新-或者检测他们的联系数据。他还有一个顶部“What\'s new”页面来展示联系人的更新,一个“me”页面包含有通告和你的喜好。他的功能并没有Windows phone中那么顺畅(例如,他没有联系人组),并且好像没有能力融合不同的联系人,整体的展现联系人),但是他已经做得很好了。\r\n你所有的联系都聚合了一系列服务。\r\n虽然社交网络使得用户应用非常有用,但大多数时间我们并不想看我们的联系人-我们只想和他们做点什么,例如给他们发邮件或即时信息。我们可以用两种方式来做这些。我们可以打开用户应用,选出一个人,给他们发邮件地址或者IM信息,然后开始交流,并加入一次会话。\r\n当我们用这种方式来进行反思,用户应用就相当于一个“选择器”,一个具体的大屏幕是你能从一个列表中选出联系人。这是联系人就在用户应用里,然后再需要的时候传递给信息和邮件。通话应用也包括他们想要的信息和他们是否需要即时通讯,用户应用改变了用户设置。\r\n这个系统是可延展的。你可以提供多种多样联系应用,他们列在一张表中以便你们能够选用,尽管现在没有很多选择。\r\n目前,用户应用是唯一可联系的应用,但是它可以提供很多其他的选择。\r\n这些应用中的链接使用了一个微软称之为“contacts”的系统,一个具体的,使用可以互相调用,并且可以注册系统的API。联系选择并不是唯一的联系,应用能提供详实的选择器来加载和保存文件,并且有其他的联系方式,比如“share”,例如一个网页链接可以通过邮件分享。Android长时间使用相似的系统,叫做“intents”.\r\n结果是整洁的小应用可以一起良好的工运行,并且可以将效果提高到一个Windows从未达到过的高度。它是一个不同的使用应用的方式,一个不同的创建方式,但是这个箱式项目展现出它是一个很好的方式。\r\n以下是英文版原文(原文地址:http://arstechnica.com/microsoft/news/2012/03/windows-8s-new-way-of-working-messaging-mail-and-people.ars?utm_source=rss&utm_medium=rss&utm_campaign=rss):\r\nWindows 8\'s new way of working: Messaging, Mail, and People

\r\n
By Peter Bright | Published about 14 hours ago
\r\n
\r\n\r\nWindows 8 is a very different Windows. We\'ve already seen that it will require Windows users to learn new ways of interacting with their computers, but there\'s more to it than that. The way applications work and interact with each other on the new platform is new and different—and rather good.\r\n\r\nThe Windows 8 Consumer Preview comes with a handful of apps pre-installed, with a few dozen more available to download via the Windows Store. Microsoft has warned that these apps are mere previews, saying in Barcelona \"Now is not a good time to start reviewing the apps, or listing them, or categorizing them.\" so we\'re not going to review them. But taking a closer look to understand how they work and fit together will reveal a lot about the way Windows 8 will work.\r\n \r\n\r\nThe preinstalled People, Messaging, and Mail apps in particular demonstrate the new Windows 8 way of using (and, for developers, building) apps.\r\n\r\n\r\n\r\nMost instant messaging services have their own notion of a contact list that\'s maintained privately by the instant messaging application. The same is not uncommon for e-mail applications. These applications build and manage these lists, and have to provide a UI to do that.\r\n\r\n \r\n\r\n \r\n
\r\n
\"The
\r\n
\r\n
The messaging app is very simple, but the basic design seems to work nicely.
\r\n
\r\n
\r\nTechnically, there\'s nothing preventing this same style of application development in Windows 8, but the supplied apps don\'t work like that. The Messenger and Mail apps have no contacts lists of their own. Instead, they can call up the People app and let you pick contacts there.\r\n\r\n\r\nWindows Phone users will be familiar with the basic concept of the People app, as it\'s not dissimilar to the People hub from Windows Phone. It aggregates contacts from a wide range of sources into a single unified view.\r\n
\r\n
\"The
\r\n
\r\n
The Messaging app\'s snapped view.\r\n
\r\n
\r\n
\r\n Contacts can come from a range of sources: Windows Live/Hotmail, Twitter, Exchange, Facebook, LinkedIn, MySpace (honestly!), and Google. You can drill down into each contact to find out more about them and what they\'re up to—it\'ll show their latest status updates on their social networks—or examine their contact data. There\'s also a top-level \"What\'s New\" page to show all the updates from your contacts, and a \"Me\" page that includes notifications and the like. The functionality isn\'t as polished as it is in Windows Phone (for example, there are no contact groups, and there seems to be no ability to fuse different contacts representing the same people into unified contacts), but it gets the job done.\r\n
\r\n
\"All
\r\n
\r\n
All your contacts, aggregated from a bunch of services.
\r\n
\r\n
\r\nWhile the social networking features make the People app useful in its own right, much of the time we don\'t just want to look at our contacts—we want to actually do something with them, such as send them an e-mail or an instant message. We can do this two ways. We can start in the People app, pick a contact, and then tap their e-mail address or IM details, or we can start our preferred communications program, and then initiate a conversation.\r\n
\r\n
\"Drilling
\r\n
\r\n
Drilling down into the \"me\" page.
\r\n
\r\n
\r\nWhen called into action in this way, the People app appears as a \"picker\": a specialized widescreen view that lets you pick contacts from a list. This way, contacts live inside the People app, and are passed to Messaging and Mail on an as-needed basis. The calling apps also indicate what information they want to know, and whether they need instant messaging-enabled contacts or not; the People app alters the set of contacts it offers accordingly.\r\nThe system is extensible. You can have multiple contact-providing applications, and they\'re put into a list so you can switch between them, though at the current time there aren\'t many options.\r\n
\r\n
\"At
\r\n
\r\n
At the moment the People app is the only thing I have that actually has contacts. But in principle, this could offer all sorts of other options.
\r\n
\r\n
\r\nThese fixed-purpose, well-defined links between applications use a system Microsoft calls \"contracts\": specific APIs that applications can offer each other and register with the system. Contact picking isn\'t the only contract; applications can offer similar pickers for loading and saving files, and there are other contracts for other operations, such as a \"share\" contract that allows, for example, a link to a webpage to be shared via e-mail. Android has long used a similar system, which it calls \"intents.\"\r\nThe result is neat little apps that work well with each other, and provide a level of consistency that Windows has never previously achieved. It\'s a different way of using apps, and a different way of writing them, but the in-box programs show that it\'s a good way.\r\n\r\n
\r\n\r\n\r\n\r\n\"\"\r\n\r\n\r\n
\r\n

 

\r\n
\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2995, 'great-qin-empire-china-has-the-best-looking-of-a-historical-drama', '《大秦帝国》中国至今最好看的一部历史剧', '2012-03-04 22:20:41', '2019-08-22 14:38:56', '

[copy]great-qin-empire-china-has-the-best-looking-of-a-historical-drama[/copy]

\r\n

如果问我2009年12月份业余最大的收获是什么?我一定说我看了一部最经典的历史剧《大秦帝国》。而不是看电影《十月围城》。

\r\n

在看《大秦帝国》之前,我只知道秦朝有秦始皇嬴政,而不知道秦始皇的老祖宗秦孝公的魄力胸怀志向不亚于中国任何一位帝王。

\r\n

在看《大秦帝国》之前,我只知道“商鞅变法”,不知道商鞅变法的坎坷和对中华民族的影响何其大,更不知道商鞅何其的伟大。

\r\n

在看《大秦帝国》之前,我只知道君臣之间最伟大“友谊”之一有唐太宗和魏征,不知道有秦孝公和商鞅之友谊感动天地……

\r\n

“赳赳老秦,共赴国难”、“公如青山,我如松柏”、“飓风过岗,伏草惟存”……念着这些经典、感人的台词,我来说出为什么《大秦帝国》是中国至今最好看的历史剧的大理由。

\r\n

理由一:看秦朝弱到强全景

\r\n

由于我国的历史教育问题,我们第一次接触“秦朝”这个词,只有嬴政统一中国的过程开始,而不知道秦朝崛起强大的背后有多少伟人为之付出的血泪和生命。秦朝从一个穷到叮当响,民不聊生,满目疮痍的诸侯小国,甚至沦落到被其他六国随意宰割、羞辱。这些给我一直认为秦国本来就是“强者”,秦国本来就有战无不胜的新骑“锐士”,秦国本来就有攻无不克的强弓利矛。在我们新中国崛起、强大的同时,有多少人还知道我们也有被八国联军羞辱过,被学习我们老祖先的小日本耻辱过。以史为鉴,可以知兴替!

\r\n

理由二:惊“商鞅变法”的伟大

\r\n

易经有云:穷则变,变则通,通则久。“商鞅变法”是史书上的著名篇章,我和大多数人一样,可能只闻其名而不知变法具体内容和经过,积贫积弱的秦国是如何通过变法走向国富民强,乃至成为战国霸主的?而战国时期的“商鞅变法”是推动封建制取代奴隶制的最大动力,其浩天功绩堪比美国的林肯。遗憾的是历史书和影视作品没有为国人详尽展示。而今《大秦帝国》补足了这一空白。在那个离我们遥远的时代,变法是一种理想抱负。看《大秦帝国》,要看以商鞅为首的变法者们是如何在秦国兴土木、练新军、发展商业,挽狂澜于既倒,扶大厦之将倾,将一个奄奄一息的国家推上战国霸主地位。

\r\n

理由三:品乱世君臣伟谊、恋人长情

\r\n

我们读过马克思和恩格斯的《伟大友谊》,但秦孝公和商鞅的友谊有过之而无不及。他们为了强国的共同信念立下“公如青山,我如松柏;君臣相知,永不相负”的誓言,这两个两千多年前的男人通过荧屏将一段“励志史”跃然于观众面前,震撼人心。

\r\n

自古英雄配美人,有英雄争霸业当然也少不了美人倾芳心,成功男人的背后大都有个女人默默支持,剧中也是如此:秦孝公之于玄奇,商鞅之于白雪和荧玉,如此种种,每份爱情都有各自不同的形态,“晴天飞雪共饮毒酒”、“荧玉一夜之间白发苍苍”和“秦公与玄奇的不移、不易、不离、不弃”无一例外都很动人。“执子之手,与子偕老。风雨白头,悠悠我心。”此等情怀,值得再三品味深思。

\r\n

理由四:观军师名家战场谋略

\r\n

赳赳老秦,共赴国难,血不流干,死不休战。作为一部历史剧,《大秦帝国》在战争场面上下足功夫。先秦还处于冷兵器时代,因而打仗时更多的是近身肉搏战。本剧为表现战争动用了大批群众演员,大多是真人上场,不用电脑特技,尽可能地还原冷兵器时代的武器以及交战特色,场面宏大惊心动魄。两国交战,武力重要,谋略则更加重要。看《大秦帝国》,不可忽略其中精彩的兵家谋略之术,对商鞅带兵收复河西之战战术战略运用描述得淋漓尽致。看古代军事家庞涓、孙膑之辈们挥斥方遒;譬如强强联合、围魏救赵、等而围之、缓兵之计等等。

\r\n

理由五:学战国古典文化

\r\n

通过看了《大秦帝国》和自己的看书,提起了我对古代文化的兴趣,了解秦国的发展史,知道了春秋战国了名家军师,学习了名言名句……

\r\n

战国时代虽然战乱频发,民不聊生,但在思想方面却是历史上最为光辉灿烂的一段。乱世之中,人人都想以自己的学识见解救世,故而当时学派林立百家争鸣,人人都可以自由地抒发自己的。正像剧中的论战台所展现的一样,论辩之术是当时的士子们必备之技,各派都有自己独特见解,各抒己见互相交流。另外,以自己的政见和策略游说诸侯以取得认可,也是当时的常见之举。看《大秦帝国》,要看其中所展现出来的古典文化风气,战国时占重要地位的法、儒、兵、墨等各家学派的思想,在《大秦帝国》剧中都有墨笔提及和表现。

\r\n

理由六:赞演员精湛演技

\r\n

商鞅的扮演者王志飞,我在电视剧《高纬度战栗》知道了他是一位难得的后起之秀;秦孝公的扮演着侯勇,在《大秦帝国》中的精湛表演让我刮目相看。还有演荧玉公主的齐芳,演公子昂的王辉等人每个角色都有血有肉、栩栩如生。商鞅的冷峻犀利,孝公的持重谨慎,荧玉公主的深明大义,公子昂的迂腐无能,整部剧犹如一卷画轴,里面的人物表演精气神韵都颇为到位。看《大秦帝国》,也是享受演员们精湛演技的过程。

\r\n

国仇与家恨,友情与爱情,血性与懦弱,刚直与阴险,阴谋与阳谋,变革与守旧……都在《大秦帝国》一一精彩的呈现。《大秦帝国》——不愧是中国至今最好看的历史剧。

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2996, 'c-typedef-struct-with-struct-differences', 'C++中typedef struct与struct的区别', '2012-03-04 01:39:12', '2019-03-25 21:29:22', '第一篇:typedef struct与struct的区别\r\n\r\n1. 基本解释\r\n\r\ntypedef为C语言的关键字,作用是为一种数据类型定义一个新名字。这里的数据类型包括内部数据类型(int,char等)和自定义的数据类型(struct等)。\r\n\r\n在编程中使用typedef目的一般有两个,一个是给变量一个易记且意义明确的新名字,另一个是简化一些比较复杂的类型声明。\r\n\r\n至于typedef有什么微妙之处,请你接着看下面对几个问题的具体阐述。\r\n\r\n2. typedef & 结构的问题\r\n\r\n当用下面的代码定义一个结构时,编译器报了一个错误,为什么呢?莫非C语言不允许在结构中包含指向它自己的指针吗?请你先猜想一下,然后看下文说明:\r\n\r\ntypedef struct tagNode\r\n{\r\nchar *pItem;\r\npNode pNext;\r\n} *pNode;\r\n\r\n答案与分析:\r\n\r\n1、typedef的最简单使用\r\n\r\ntypedef long byte_4;\r\n\r\n给已知数据类型long起个新名字,叫byte_4。\r\n\r\n2、 typedef与结构结合使用\r\n\r\ntypedef struct tagMyStruct\r\n{\r\nint iNum;\r\nlong lLength;\r\n} MyStruct;\r\n\r\n这语句实际上完成两个操作:\r\n\r\n1) 定义一个新的结构类型\r\n\r\nstruct tagMyStruct\r\n{\r\nint iNum;\r\nlong lLength;\r\n};\r\n\r\n分析:tagMyStruct称为“tag”,即“标签”,实际上是一个临时名字,struct 关键字和tagMyStruct一起,构成了这个结构类型,不论是否有typedef,这个结构都存在。\r\n\r\n我们可以用struct tagMyStruct varName来定义变量,但要注意,使用tagMyStruct varName来定义变量是不对的,因为struct 和tagMyStruct合在一起才能表示一个结构类型。\r\n\r\n2) typedef为这个新的结构起了一个名字,叫MyStruct。\r\n\r\ntypedef struct tagMyStruct MyStruct;\r\n\r\n因此,MyStruct实际上相当于struct tagMyStruct,我们可以使用MyStruct varName来定义变量。\r\n\r\n答案与分析\r\n\r\nC语言当然允许在结构中包含指向它自己的指针,我们可以在建立链表等数据结构的实现上看到无数这样的例子,上述代码的根本问题在于typedef的应用。\r\n\r\n根据我们上面的阐述可以知道:新结构建立的过程中遇到了pNext域的声明,类型是pNode,要知道pNode表示的是类型的新名字,那么在类型本身还没有建立完成的时候,这个类型的新名字也还不存在,也就是说这个时候编译器根本不认识pNode。\r\n\r\n解决这个问题的方法有多种:\r\n\r\n1)、\r\n\r\ntypedef struct tagNode\r\n{\r\nchar *pItem;\r\nstruct tagNode *pNext;\r\n} *pNode;\r\n\r\n2)、\r\n\r\ntypedef struct tagNode *pNode;\r\nstruct tagNode\r\n{\r\nchar *pItem;\r\npNode pNext;\r\n};\r\n\r\n注意:在这个例子中,你用typedef给一个还未完全声明的类型起新名字。C语言编译器支持这种做法。\r\n\r\n3)、规范做法:\r\n\r\ntypedef uint32 (* ADM_READDATA_PFUNC)( uint16*, uint32 );\r\n\r\n这个以前没有看到过,个人认为是预定义一个uint32的指针函数,uint16*, uint32 为函数里的两个参数; 应该相当于#define uint32 (* ADM_READDATA_PFUNC)( uint16*, uint32 );\r\n\r\nstruct在代码中常见两种形式:\r\nstruct A\r\n{\r\n//...\r\n};\r\n\r\nstruct\r\n{\r\n//...\r\n} A;\r\n这其实是两个完全不同的用法:\r\n前者叫做“结构体类型定义”,意思是:定义{}中的结构为一个名称是“A”的结构体。\r\n这种用法在typedef中一般是:\r\ntypedef struct tagA //故意给一个不同的名字,作为结构体的实名\r\n{\r\n//...\r\n} A; //结构体的别名。\r\n\r\n后者是结构体变量定义,意思是:以{}中的结构,定义一个名称为\"A\"的变量。这里的结构体称为匿名结构体,是无法被直接引用的。\r\n也可以通过typedef为匿名结构体创建一个别名,从而使得它可以被引用:\r\ntypedef struct\r\n{\r\n//...\r\n} A; //定义匿名结构体的别名为A\r\n\r\n第二篇:在C和C++中struct和typedef struct的区别\r\n\r\n在C和C++有三种定义结构的方法。\r\n\r\ntypedef struct {\r\n\r\nint data;\r\n\r\nint text;\r\n\r\n} S1;\r\n\r\n//这种方法可以在c或者c++中定义一个S1结构\r\n\r\nstruct S2 {\r\n\r\nint data;\r\n\r\nint text;\r\n\r\n};\r\n\r\n// 这种定义方式只能在C++中使用,而如果用在C中,那么编译器会报错\r\n\r\nstruct {\r\n\r\nint data;\r\n\r\nint text;\r\n\r\n} S3;\r\n\r\n这种方法并没有定义一个结构,而是定义了一个s3的结构变量,编译器会为s3内存。\r\n\r\nvoid main()\r\n\r\n{\r\n\r\nS1 mine1;// OK ,S1 是一个类型\r\n\r\nS2 mine2;// OK,S2 是一个类型\r\n\r\nS3 mine3;// OK,S3 不是一个类型\r\n\r\nS1.data = 5;// ERRORS1 是一个类型\r\n\r\nS2.data = 5;// ERRORS2 是一个类型\r\n\r\nS3.data = 5;// OKS3是一个变量\r\n\r\n}\r\n\r\n另外,对与在结构中定义结构本身的变量也有几种写法\r\n\r\nstruct S6 {\r\n\r\nS6* ptr;\r\n\r\n};\r\n\r\n// 这种写法只能在C++中使用\r\n\r\ntypedef struct {\r\n\r\nS7* ptr;\r\n\r\n} S7;\r\n\r\n// 这是一种在C和C++中都是错误的定义\r\n\r\n如果在C中,我们可以使用这样一个“曲线救国的方法“\r\n\r\ntypedef struct tagS8{\r\n\r\ntagS8 * ptr;\r\n\r\n} S8;\r\n\r\n第三篇:struct和typedef struct\r\n\r\n分三块来讲述:\r\n1 首先:\r\n在C中定义一个结构体类型要用typedef:\r\ntypedef struct Student\r\n{\r\nint a;\r\n}Stu;\r\n于是在声明变量的时候就可:Stu stu1;\r\n如果没有typedef就必须用struct Student stu1;来声明\r\n这里的Stu实际上就是struct Student的别名。\r\n另外这里也可以不写Student(于是也不能struct Student stu1;了)\r\ntypedef struct\r\n{\r\nint a;\r\n}Stu;\r\n但在c++里很简单,直接\r\nstruct Student\r\n{\r\nint a;\r\n};\r\n于是就定义了结构体类型Student,声明变量时直接Student stu2;\r\n===========================================\r\n2其次:\r\n在c++中如果用typedef的话,又会造成区别:\r\nstruct Student\r\n{\r\nint a;\r\n}stu1;//stu1是一个变量\r\ntypedef struct Student2\r\n{\r\nint a;\r\n}stu2;//stu2是一个结构体类型\r\n使用时可以直接访问stu1.a\r\n但是stu2则必须先 stu2 s2;\r\n然后 s2.a=10;\r\n===========================================\r\n3 掌握上面两条就可以了,不过最后我们探讨个没多大关系的问题\r\n如果在c程序中我们写:\r\ntypedef struct\r\n{\r\nint num;\r\nint age;\r\n}aaa,bbb,ccc;\r\n这算什么呢?\r\n我个人观察编译器(VC6)的理解,这相当于\r\ntypedef struct\r\n{\r\nint num;\r\nint age;\r\n}aaa;\r\ntypedef aaa bbb;\r\ntypedef aaa ccc;\r\n也就是说aaa,bbb,ccc三者都是结构体类型。声明变量时用任何一个都可以,在c++中也是如此。但是你要注意的是这个在c++中如果写掉了typedef关键字,那么aaa,bbb,ccc将是截然不同的三个对象。\r\n\r\n第四篇:C/C++中typedef struct和struct的用法\r\n\r\nstruct _x1 { ...}x1; 和 typedef struct _x2{ ...} x2; 有什么不同?\r\n\r\n其实, 前者是定义了类_x1和_x1的对象实例x1, 后者是定义了类_x2_x2的类别名x2 ,\r\n\r\n所以它们在使用过程中是有取别的.请看实例1.\r\n\r\n[知识点]\r\n\r\n结构体也是一种数据类型, 可以使用结构变量, 因此, 象其它 类型的变量一样, 在使用结构变量时要先对其定义。\r\n\r\n定义结构变量的一般格式为:\r\n\r\nstruct 结构名\r\n\r\n{\r\n\r\n类型 变量名;\r\n\r\n类型 变量名;\r\n\r\n...\r\n\r\n} 结构变量;\r\n\r\n结构名是结构的标识符不是变量名。\r\n\r\n另一种常用格式为:\r\n\r\ntypedef struct 结构名\r\n\r\n{\r\n\r\n类型 变量名;\r\n\r\n类型 变量名;\r\n\r\n...\r\n\r\n} 结构别名;\r\n\r\n另外注意: 在C中,struct不能包含函数。在C++中,对struct进行了扩展,可以包含函数。\r\n\r\n======================================================================\r\n\r\n实例1: struct.cpp\r\n\r\n#include <iostream>\r\n\r\nusing namespace std;\r\n\r\ntypedef struct _point{\r\n\r\nint x;\r\n\r\nint y;\r\n\r\n}point; //定义类,给类一个别名\r\n\r\nstruct _hello{\r\n\r\nint x,y;\r\n\r\n} hello; //同时定义类和对象\r\n\r\nint main()\r\n\r\n{\r\n\r\npoint pt1;\r\n\r\npt1.x = 2;\r\n\r\npt1.y = 5;\r\n\r\ncout<< \"ptpt1.x=\" << pt1.x << \"pt.y=\" <<pt1.y <<endl;\r\n\r\n//hello pt2;\r\n\r\n//pt2.x = 8;\r\n\r\n//pt2.y =10;\r\n\r\n//cout<<\"pt2pt2.x=\"<< pt2.x <<\"pt2.y=\"<<pt2.y <<endl;\r\n\r\n//上面的hello pt2;这一行编译将不能通过. 为什么?\r\n\r\n//因为hello是被定义了的对象实例了.\r\n\r\n//正确做法如下: 用hello.x和hello.y\r\n\r\nhello.x = 8;\r\n\r\nhello.y = 10;\r\n\r\ncout<< \"hellohello.x=\" << hello.x << \"hello.y=\" <<hello.y <<endl;\r\n\r\nreturn 0;\r\n\r\n}\r\n\r\n第五篇:问答\r\n\r\nQ:用struct和typedef struct 定义一个结构体有什么区别?为什么会有两种方式呢?\r\n\r\nstruct Student\r\n{\r\nint a;\r\n} stu;\r\ntypedef struct Student2\r\n{\r\nint a;\r\n}stu2;\r\n\r\nA:\r\n\r\n事实上,这个东西是从C语言中遗留过来的,typedef可以定义新的复合类型或给现有类型起一个别名,在C语言中,如果你使用\r\nstruct xxx\r\n{\r\n}; 的方法,使用时就必须用 struct xxx var 来声明变量,而使用\r\ntypedef struct\r\n{\r\n}的方法 就可以写为 xxx var;\r\n不过在C++中已经没有这回事了,无论你用哪一种写法都可以使用第二种方式声明变量,这个应该算是C语言的糟粕。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2997, 'java-se-tutorial-2-native-data-type-primitive-data-type', 'Java SE教程2:原生数据类型 Primitive Data Type', '2012-02-27 22:50:06', '2019-11-30 14:08:58', '
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2998, 'java-learning-note-001-1-1-under-win7-download-and-install-jdk', 'Java学习笔记001:【1.1】Win7下JDK的下载与安装', '2012-02-27 22:40:16', '2019-03-25 21:29:22', '
1、下载jdk\r\n==========\r\n\r\n平台|地址\r\n--|--|\r\nX86|http://download.oracle.com/otn-pub/java/jdk/7u71-b14/jdk-7u71-windows-i586.exe\r\nX64|http://download.oracle.com/otn-pub/java/jdk/7u71-b14/jdk-7u71-windows-x64.exe\r\n我这里下载的是x64版本。\r\n\r\n2、安装JDK\r\n==========\r\n安装非常easy了,和安装其它软件没啥差别,路径假设不须要自己特殊设置的话,就能够一路默认。须要知道安装的路径,配置的时候是须要用到的,安装后\r\n我这的安装路径是 ```D:\\Program Files\\Java\\jdk1.7.0_71\\```\r\n\r\n3、环境变量的设置\r\n==================\r\n需要设置JAVA_HOME、CLASSPATH、Path三个环境变量。\r\n\r\na)、右击“计算机”,点击“属性”,点击弹出界面的左部分的“高级系统设置”,选择“高级”选项卡,点击下部的“环境变量”,在“系统变量”中,需要设置3个属性```JAVA_HOME、CLASSPATH、Path```(不区分大写和小写),若已存在则点击“编辑”,不存在则点击“新建”;\r\n![](http://bcs.duapp.com/terwer/blog/2015/03/0_1277867103ZVKR.gif)\r\n\r\nb)、```JAVA_HOME```指明安装JDK路径,就是刚才安装时所选择的路径```D:\\Program Files\\Java\\jdk1.7.0_71\\```,此路径下包含lib,bin,jre等目录(此变量最好设置,由于以后执行tomcat,eclipse等都须要依此变量);\r\n\r\nc)、Path使得系统能够在不论什么路径下识别java命令,这里,要注意下,path应该是本来就存在的,就不要新建了,找到path,点击“编辑”;在值的最前面加上以下的语句就可以。假设覆盖了path变量,将导致的cmd下有些主要的命令会找不到。\r\n```%JAVA_HOME%\\bin;%JAVA_HOME%jrebin;```\r\n\r\nd)、CLASSPATH为java载入类(class or lib)路径,仅仅有类在classpath中,java命令才干识别,设为:\r\n ```.;%JAVA_HOME%/lib/dt.jar;%JAVA_HOME%/lib/tools.jar``` (要加.表示当前路径)\r\n ```%JAVA_HOME%```就是引用前面指定的```JAVA_HOME```;\r\n\r\n4、检验安装配置是否正确\r\n\r\n点击“开始”,键入“cmd”;\r\n\r\n执行“java -version”、“java”、“javac”三个命令,如果能正常运行,说明安装配置ok了。\r\n\r\n以下就能够开始java之旅。
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (2999, 'on-the-coins-and-the-emblem-question', '一道关于硬币和国徽的题', '2012-02-27 04:55:15', '2019-03-25 21:29:22', '
题目:袋中装有m只正品硬币,n只次品硬币(次品硬币的两面均和有国徽),在袋中任取一只,将它投掷r次,已知每次都得到国徽,问这只硬币是正品的概率是多少?
\r\n
\r\n详细解答如下
\r\n
\"\"
\r\n
\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3000, 'xu-wei-blue-lotus', '许巍-蓝莲花', '2012-02-24 22:53:46', '2019-09-03 11:43:10', '', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3001, 'the-audit-had-passed-without-finding-the-net-comes-with-3-invitation-code-email', '终于通过无觅网的审核了,附送3个邀请码,要的留邮箱', '2012-02-24 21:42:19', '2019-03-25 21:29:22', '    加入“无觅网络”已经有了段时间,其并不只是单单提供“相关文章”的功能,共重要的是将无数个博客、论坛等系统通过这一插件联系到了一起,达到“你中有我,我中有你”的目的,俨然一个“博客圈”。\r\n\r\n    不过“无觅网”还处于测试期,读取他人相关文章的功能还需要邀请,我也是偶然的机会在朋友的博客里看到才要了一个邀请码,现在我手里也有了三个邀请名额,有需要的童鞋请留下邮箱,我发给你。就3个,先来先得。\"\"', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3002, 'graph-class-of-computational-problems', '关于图的一类计算问题', '2012-02-23 04:56:57', '2019-03-25 21:29:22', '    已知无向图G的邻接矩阵为\"\",则G有( ).\r\nA. 5点,8边     B. 6点,7边     C. 6点,8边     D. 5点,7边\r\n解答:行(列)数表示点的个数,5个点。1的个数除以2为边的个数,7条边。选D。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3004, 'on-trees-in-a-class-of-computational-problems', '关于树的一类计算问题', '2012-02-23 04:24:44', '2019-03-25 21:29:22', '在一棵树中有7片树叶,3个3度结点,其余都是4度结点则该树有( )个4度结点。\r\n(A)1    (B)2    (C )3    (D)4\r\n答:正确答案是:A\r\n\r\n设该树有x个4度结点。\r\n树的总度数为:1*7+3*3+4x = 4x+16\r\n树的总结点数:7+3+x =x+10\r\n边数=结点数-1,所以边数为:x+9\r\n树的总度数为边数的2倍,所以\r\n4x+16 = (x+9)*2\r\n解得:x=1\r\n用到的定理:e=v-1 (e为边数,v为结点数)\r\n                    deg=2e(deg为总度数)', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3005, 'detailed-explanation-of-evaluating-hasse-diagram', '哈斯图详解', '2012-02-23 04:11:15', '2019-03-25 21:29:22', '        如图,图中的每个结点表示集合A中的一个元素,结点的位置按它们在偏序中的次序从底向上排列。即对任意a,b属于A,若a≤b且a≠b,则a排在b的下边。如果a≤b且a≠b,且不存在c∈A满足a≤c且c≤b,则在a和b之间连一条线。这样画出的图叫哈斯图。\r\n
 
\r\n        哈斯图的作图法为:\r\n  (1)以“圆圈”表示元素;\r\n(2)若x≤y,则y画在x的上层;\r\n  (3)若y覆盖x,则连线;\r\n  (4)不可比的元素可画在同一层。\r\n

        例题:设集合P={x1x2x3x4x5}上的偏序关系如图2所示,则下列说法中正确的是(A

\r\n

AP的最大元素为x1 ,无最小元素,极小元素为x4x5 ,极大元为素x1

\r\n

BP无最大元素,也无最小元素,极小元素为x4x5 ,极大元为素x1

\r\n

CP的最大元素为x1 ,无最小元素,也无极小元素 ,极大元为素x1

\r\n

DP的最大元素为x1 ,最小元素为x4x5,极小元素为x4x5 ,极大元为素x1\r\n        \"\"\r\n(从上到下,从左到右依次是x1,x2,x3,x4,x5)

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3006, 'how-to-use-laptop-smartphone-internet-for-example-in-andrews', '智能手机如何利用笔记本上网(以安卓为例)', '2012-01-29 00:11:51', '2019-03-25 21:29:22', '

[copy]how-to-use-laptop-smartphone-internet-for-example-in-andrews[/copy]

\r\n

工具/原料

\r\n

1.一根网线;

\r\n

2.系统的笔记本电脑(或有外置无线网卡的台式机),确保笔记本的无线网络功能打开;

\r\n

3.功能的手机一台。

\r\n

步骤/方法

\r\n

1.win键+R打开运行程序,输入cmd并回车打开命令指令符,在命令指令符中输入netsh wlan set hostednetwork mode=allow ssid=wifi key=12345678,然后回车,其中红色内容可以自己设定,ssid是wifi名,key是你连接wifi所需的密码,我设定的ssid是wifi,密码为12345678,如下图:\"2012021739014205\"

\r\n

2.确保无线网络打开(一般笔记本上会有无线网络打开的指示灯),打开控制面板---网络和Internet---网络和共享中心---更改适配器设置(在左上),选中你当前的宽带连接并右键属性---共享---允许其他用户通过此计算机的Internet来连接(非常重要,一定要设置共享,否则仅仅是连上了,但不能上网,只有共享了才能上网)打勾,共享网络选择无线网络连接 2,这时你的宽带连接会出现共享的字样,如下图:
 \"2012021739184377\"
回到命令指令符,输入:netsh wlan start hostednetwork,回车,显示以下内容,无线网络共享打开成功,如下图:\"2012021739320173\"

 这个每次开机时都要打开一次,如果嫌麻烦可以把netsh wlan start hostednetwork复制进txt然后将txt扩展名保存为bat,文件可以重命名为打开无线共享等一目了然的名字。

 
这时候无线网络连接 2的红叉就不见了,成了一个正常的网络。
\"2012021739802645\"

\r\n

3.接下来你就可以用其他设备搜索你设置的ssid网,并输入你设置的密码即可连接wifi了,如图(我设定的ssid是wifi,密码为12345678,连接时输入12345678即可),连接好后就可以用wifi进行上网了。附上效果图:
\"2012021741024229\"

\r\n

我用的是2M的有线网,所以下载速度在200多KB。

\r\n

注意事项

\r\n

XP也可以共享无线网络,只是安卓2.2之前不支持XP的AD-HOC(需要补丁破解),Connectify(只支持win7)和Bzeek(支持win7和XP)也可实现共享,可以自己去搜教程,XP系统建议用Bzeek(安卓手机请自行百度XP下解决办法)此教程为方法之一,还可以直接在win7网络中心建立临时网络(这个方法请自行百度之)。

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3007, 'yang-and-jacky-lau-wai-barking', '杨幂&刘恺威-错怪', '2012-01-26 04:35:17', '2019-09-08 17:09:29', '
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3009, 'java-static-final-keyword-summary', 'Java中static与final关键字使用总结', '2012-01-26 04:10:48', '2019-11-29 01:15:24', '
一、static
\r\n

\r\n    static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,但是Java语言中没有全局变量的概念。
\r\n

\r\n    被static修饰的成员变量和成员方法独立于该类的任何对象。也就是说,它不依赖类特定的实例,被类的所有实例共享。只要这个类被加载,Java虚拟机就能根据类名在运行时数据区的方法区内定找到他们。因此,static对象可以在它的任何对象创建之前访问,无需引用任何对象。
\r\n

\r\n    用public修饰的static成员变量和成员方法本质是全局变量和全局方法,当声明它类的对象时,不生成static变量的副本,而是类的所有实例共享同一个static变量。
\r\n
\r\n
    static变量前可以有private修饰,表示这个变量可以在类的静态代码块中,或者类的其他静态成员方法中使用(当然也可以在非静态成员方法中使用--废话),但是不能在其他类中通过类名来直接引用,这一点很重要。实际上你需要搞明白,private是访问权限限定,static表示不要实例化就可以使用,这样就容易理解多了。static前面加上其它访问权限关键字的效果也以此类推。
\r\n
\r\n
    static修饰的成员变量和成员方法习惯上称为静态变量和静态方法,可以直接通过类名来访问,访问语法为:
\r\n类名.静态方法名(参数列表...) 
\r\n类名.静态变量名
\r\n
    用static修饰的代码块表示静态代码块,当Java虚拟机(JVM)加载类时,就会执行该代码块(用处非常大,呵呵)。
\r\n
\r\n
1、static变量
\r\n按照是否静态的对类成员变量进行分类可分两种:一种是被static修饰的变量,叫静态变量类变量;另一种是没有被static修饰的变量,叫实例变量。两者的区别是:
\r\n对于静态变量在内存中只有一个拷贝(节省内存),JVM只为静态分配一次内存,在加载类的过程中完成静态变量的内存分配,可用类名直接访问(方便),当然也可以通过对象来访问(但是这是不推荐的)。
\r\n对于实例变量,每创建一个实例,就会为实例变量分配一次内存,实例变量可以在内存中有多个拷贝,互不影响(灵活)。
\r\n
\r\n
2、静态方法
\r\n静态方法可以直接通过类名调用,任何的实例也都可以调用,因此静态方法中不能用this和super关键字,不能直接访问所属类的实例变量和实例方法(就是不带static的成员变量和成员成员方法),只能访问所属类的静态成员变量和成员方法。因为实例成员与特定的对象关联!这个需要去理解,想明白其中的道理,不是记忆!!!
\r\n因为static方法独立于任何实例,因此static方法必须被实现,而不能是抽象的abstract。
\r\n
\r\n
3、static代码块
\r\nstatic代码块也叫静态代码块,是在类中独立于类成员的static语句块,可以有多个,位置可以随便放,它不在任何的方法体内,JVM加载类时会执行这些静态的代码块,如果static代码块有多个,JVM将按照它们在类中出现的先后顺序依次执行它们,每个代码块只会被执行一次。例如:
\r\n
\r\n
\r\n
\r\n
public class Test5 { 
\r\nprivate static int a; 
\r\nprivate int b; 
\r\n
\r\nstatic { 
\r\nTest5.a = 3; 
\r\nSystem.out.println(a); 
\r\nTest5 t = new Test5(); 
\r\nt.f(); 
\r\nt.b = 1000; 
\r\nSystem.out.println(t.b); 
\r\n} 
\r\n
\r\nstatic { 
\r\nTest5.a = 4; 
\r\nSystem.out.println(a); 
\r\n} 
\r\n
\r\npublic static void main(String[] args) { 
\r\n// TODO 自动生成方法存根 
\r\n} 
\r\n
\r\nstatic { 
\r\nTest5.a = 5; 
\r\nSystem.out.println(a); 
\r\n} 
\r\n
\r\npublic void f() { 
\r\nSystem.out.println(\"hhahhahah\"); 
\r\n} 
\r\n}
\r\n
\r\n
\r\n
\r\n
运行结果:
\r\n
3
\r\nhhahhahah
\r\n1000
\r\n4
\r\n5
\r\n
    利用静态代码块可以对一些static变量进行赋值,最后再看一眼这些例子,都一个static的main方法,这样JVM在运行main方法的时候可以直接调用而不用创建实例。
\r\n
\r\n
4、static和final一块用表示什么
\r\nstatic final用来修饰成员变量和成员方法,可简单理解为“全局常量”!
\r\n对于变量,表示一旦给值就不可修改,并且通过类名可以访问。
\r\n对于方法,表示不可覆盖,并且可以通过类名直接访问。
\r\n
       
\r\n
    特别要注意一个问题:
\r\n
    对于被static和final修饰过的实例常量,实例本身不能再改变了,但对于一些容器类型(比如,ArrayList、HashMap)的实例变量,不可以改变容器变量本身,但可以修改容器中存放的对象,这一点在编程中用到很多。
\r\n
    也许说了这么多,反倒把你搞晕了,还是看个例子吧:
\r\n
\r\n
\r\n
\r\n
public class TestStaticFinal { 
\r\nprivate static final String strStaticFinalVar = \"aaa\"
\r\nprivate static String strStaticVar = null
\r\nprivate final String strFinalVar = null
\r\nprivate static final int intStaticFinalVar = 0; 
\r\nprivate static final Integer integerStaticFinalVar = new Integer(8); 
\r\nprivate static final ArrayList<String> alStaticFinalVar = new ArrayList<String>(); 
\r\n
\r\nprivate void test() { 
\r\nSystem.out.println(\"-------------值处理前----------rn\"); 
\r\nSystem.out.println(\"strStaticFinalVar=\" + strStaticFinalVar + \"rn\"); 
\r\nSystem.out.println(\"strStaticVar=\" + strStaticVar + \"rn\"); 
\r\nSystem.out.println(\"strFinalVar=\" + strFinalVar + \"rn\"); 
\r\nSystem.out.println(\"intStaticFinalVar=\" + intStaticFinalVar + \"rn\"); 
\r\nSystem.out.println(\"integerStaticFinalVar=\" + integerStaticFinalVar + \"rn\"); 
\r\nSystem.out.println(\"alStaticFinalVar=\" + alStaticFinalVar + \"rn\"); 
\r\n
\r\n
\r\n//strStaticFinalVar=\"哈哈哈哈\";        //错误,final表示终态,不可以改变变量本身. 
\r\nstrStaticVar = \"哈哈哈哈\";                //正确,static表示类变量,值可以改变. 
\r\n//strFinalVar=\"呵呵呵呵\";                    //错误, final表示终态,在定义的时候就要初值(哪怕给个null),一旦给定后就不可再更改。 
\r\n//intStaticFinalVar=2;                        //错误, final表示终态,在定义的时候就要初值(哪怕给个null),一旦给定后就不可再更改。 
\r\n//integerStaticFinalVar=new Integer(8);            //错误, final表示终态,在定义的时候就要初值(哪怕给个null),一旦给定后就不可再更改。 
\r\nalStaticFinalVar.add(\"aaa\");        //正确,容器变量本身没有变化,但存放内容发生了变化。这个规则是非常常用的,有很多用途。 
\r\nalStaticFinalVar.add(\"bbb\");        //正确,容器变量本身没有变化,但存放内容发生了变化。这个规则是非常常用的,有很多用途。 
\r\n
\r\nSystem.out.println(\"-------------值处理后----------rn\"); 
\r\nSystem.out.println(\"strStaticFinalVar=\" + strStaticFinalVar + \"rn\"); 
\r\nSystem.out.println(\"strStaticVar=\" + strStaticVar + \"rn\"); 
\r\nSystem.out.println(\"strFinalVar=\" + strFinalVar + \"rn\"); 
\r\nSystem.out.println(\"intStaticFinalVar=\" + intStaticFinalVar + \"rn\"); 
\r\nSystem.out.println(\"integerStaticFinalVar=\" + integerStaticFinalVar + \"rn\"); 
\r\nSystem.out.println(\"alStaticFinalVar=\" + alStaticFinalVar + \"rn\"); 
\r\n} 
\r\n
\r\npublic static void main(String args[]) { 
\r\nnew TestStaticFinal().test(); 
\r\n} 
\r\n}
\r\n
\r\n
\r\n
\r\n
运行结果如下:
\r\n
-------------值处理前----------
\r\n
strStaticFinalVar=aaa
\r\n
strStaticVar=null
\r\n
strFinalVar=null
\r\n
intStaticFinalVar=0
\r\n
integerStaticFinalVar=8
\r\n
alStaticFinalVar=[]
\r\n
-------------值处理后----------
\r\n
strStaticFinalVar=aaa
\r\n
strStaticVar=哈哈哈哈
\r\n
strFinalVar=null
\r\n
intStaticFinalVar=0
\r\n
integerStaticFinalVar=8
\r\n
alStaticFinalVar=[aaa, bbb]
\r\n

\r\nProcess finished with exit code 0\r\n
\r\n二、final
\r\n    根据程序上下文环境,Java关键字final有“这是无法改变的”或者“终态的”含义,它可以修饰非抽象类、非抽象类成员方法和变量。你可能出于两种理解而需要阻止改变:设计或效率。
\r\n
    final类不能被继承,没有子类,final类中的方法默认是final的。
\r\nfinal方法不能被子类的方法覆盖,但可以被继承。
\r\nfinal成员变量表示常量,只能被赋值一次,赋值后值不再改变。
\r\nfinal不能用于修饰构造方法。
\r\n注意:父类的private成员方法是不能被子类方法覆盖的,因此private类型的方法默认是final类型的。
\r\n
\r\n
1、final类
\r\nfinal类不能被继承,因此final类的成员方法没有机会被覆盖,默认都是final的。在设计类时候,如果这个类不需要有子类,类的实现细节不允许改变,并且确信这个类不会载被扩展,那么就设计为final类。
\r\n
2、final方法
\r\n如果一个类不允许其子类覆盖某个方法,则可以把这个方法声明为final方法。
\r\n使用final方法的原因有二:
\r\n第一、把方法锁定,防止任何继承类修改它的意义和实现。
\r\n第二、高效。编译器在遇到调用final方法时候会转入内嵌机制,大大提高执行效率。
\r\n例如:
\r\n
\r\n
\r\n
public class Test1 { 
\r\npublic static void main(String[] args) { 
\r\n// TODO 自动生成方法存根 
\r\n} 
\r\npublic void f1() { 
\r\nSystem.out.println(\"f1\"); 
\r\n} 
\r\n//无法被子类覆盖的方法 
\r\npublic final void f2() { 
\r\nSystem.out.println(\"f2\"); 
\r\n} 
\r\npublic void f3() { 
\r\nSystem.out.println(\"f3\"); 
\r\n} 
\r\nprivate void f4() { 
\r\nSystem.out.println(\"f4\"); 
\r\n} 
\r\n} 
\r\npublic class Test2 extends Test1 { 
\r\n
\r\npublic void f1(){     
\r\nSystem.out.println(\"Test1父类方法f1被覆盖!\"); 
\r\n} 
\r\npublic static void main(String[] args) { 
\r\nTest2 t=new Test2(); 
\r\nt.f1();    
\r\nt.f2(); //调用从父类继承过来的final方法 
\r\nt.f3(); //调用从父类继承过来的方法 
\r\n//t.f4(); //调用失败,无法从父类继承获得 
\r\n} 
\r\n}
\r\n
\r\n
\r\n
3、final变量(常量)
\r\n用final修饰的成员变量表示常量,值一旦给定就无法改变!
\r\nfinal修饰的变量有三种:静态变量、实例变量和局部变量,分别表示三种类型的常量。
\r\n从下面的例子中可以看出,一旦给final变量初值后,值就不能再改变了。
\r\n另外,final变量定义的时候,可以先声明,而不给初值,这中变量也称为final空白,无论什么情况,编译器都确保空白final在使用之前必须被初始化。但是,final空白在final关键字final的使用上提供了更大的灵活性,为此,一个类中的final数据成员就可以实现依对象而有所不同,却有保持其恒定不变的特征。
\r\n
\r\n
\r\n
\r\n
package org.leizhimin; 
\r\n
\r\npublic class Test3 { 
\r\nprivate final String S = \"final实例变量S\"; 
\r\nprivate final int A = 100; 
\r\npublic final int B = 90; 
\r\n
\r\npublic static final int C = 80; 
\r\nprivate static final int D = 70; 
\r\n
\r\npublic final int E; //final空白,必须在初始化对象的时候赋初值 
\r\n
\r\npublic Test3(int x) { 
\r\nE = x; 
\r\n} 
\r\n
\r\n/** 
\r\n* @param args 
\r\n*/
 
\r\npublic static void main(String[] args) { 
\r\nTest3 t = new Test3(2); 
\r\n//t.A=101;    //出错,final变量的值一旦给定就无法改变 
\r\n//t.B=91; //出错,final变量的值一旦给定就无法改变 
\r\n//t.C=81; //出错,final变量的值一旦给定就无法改变 
\r\n//t.D=71; //出错,final变量的值一旦给定就无法改变 
\r\n
\r\nSystem.out.println(t.A); 
\r\nSystem.out.println(t.B); 
\r\nSystem.out.println(t.C); //不推荐用对象方式访问静态字段 
\r\nSystem.out.println(t.D); //不推荐用对象方式访问静态字段 
\r\nSystem.out.println(Test3.C); 
\r\nSystem.out.println(Test3.D); 
\r\n//System.out.println(Test3.E); //出错,因为E为final空白,依据不同对象值有所不同. 
\r\nSystem.out.println(t.E); 
\r\n
\r\nTest3 t1 = new Test3(3); 
\r\nSystem.out.println(t1.E); //final空白变量E依据对象的不同而不同 
\r\n} 
\r\n
\r\nprivate void test() { 
\r\nSystem.out.println(new Test3(1).A); 
\r\nSystem.out.println(Test3.C); 
\r\nSystem.out.println(Test3.D); 
\r\n} 
\r\n
\r\npublic void test2() { 
\r\nfinal int a;     //final空白,在需要的时候才赋值 
\r\nfinal int b = 4;    //局部常量--final用于局部变量的情形 
\r\nfinal int c;    //final空白,一直没有给赋值.    
\r\na = 3; 
\r\n//a=4;    出错,已经给赋过值了. 
\r\n//b=2; 出错,已经给赋过值了. 
\r\n} 
\r\n}
\r\n
\r\n
\r\n
\r\n
4、final参数
\r\n当函数参数为final类型时,你可以读取使用该参数,但是无法改变该参数的值。
\r\n
\r\n
\r\n
public class Test4 { 
\r\npublic static void main(String[] args) { 
\r\nnew Test4().f1(2); 
\r\n} 
\r\n
\r\npublic void f1(final int i) { 
\r\n//i++;    //i是final类型的,值不允许改变的. 
\r\nSystem.out.print(i); 
\r\n} 
\r\n}
\r\n
    看了上面这个例子,就清楚很多了,但必须明白:通过static final修饰的容器类型变量中所“装”的对象是可改变的。这是和一般基本类型和类类型变量差别很大的地方。
\r\n
\r\n
\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3011, 'detailed-explanation-of-abstract-classes-in-java', 'Java中的抽象类详解', '2012-01-17 01:12:40', '2019-03-25 21:29:22', '简介\r\n用abstract 修饰的类是抽象类。\r\n
 
\r\n  在C++中,含有纯虚拟函数的类称为抽象类,它不能生成对象。\r\n
 
\r\n  凡是包含纯虚函数的类都是抽象类。\r\n
 
\r\n  抽象类是不完整的,并且它只能用作基类。它与非抽象类的不同:\r\n
 
\r\n  1、抽象类不能直接实例化,并且对抽象类使用 new 运算符是编译时错误。虽然一些变量和值在编译时的类型可以是抽象的,但是这样的变量和值必须或者为 null,或者含有对非抽象类的实例的引用(此非抽象类是从抽象类派生的)。\r\n
 
\r\n  2、允许(但不要求)抽象类包含抽象成员。\r\n
 
\r\n  3、抽象类不能被密封\r\n
 
\r\n  当从抽象类派生非抽象类时,这些非抽象类必须具体实现所继承的所有抽象成员,从而重写那些抽象成员。在下边的示例中:\r\n
 
\r\n  abstract class A{ public abstract void F();}\r\n
 
\r\n  abstract class B: A{ public void G() {}}\r\n
 
\r\n  class C: B{ public override void F() { // actual implementation of F }} \r\n
 
\r\n   抽象类 A 引入抽象方法 F。类 B 引入另一个方法 G,但由于它不提供 F 的实现,B 也必须声明为抽象类。类 C 重写 F,并提供一个具体实现。由于 C 中没有了抽象成员,因此可以(但并非必须)将 C 声明为非抽象类。\r\n
 
\r\n  抽象类与接口紧密相关。然接口又比抽象类更抽象,这主要体现在它们的差别上:\r\n1)类可以实现无限个接口,但仅能从一个抽象(或任何其他类型)类继承,从抽象类派生的类仍可实现接口,从而得出接口是用来解决多重继承问题的。\r\n2)抽象类当中可以存在非抽象的方法,可接口不能且它里面的方法只是一个声明必须用public来修饰没有具体实现的方法。\r\n3)抽象类中的成员变量可以被不同的修饰符来修饰,可接口中的成员变量默认的都是静态常量(static final)。\r\n4)这一点也是最重要的一点本质的一点\"抽象类是对象的抽象,然而接口是一种行为规范\"。\r\n
 
\r\n

定义

\r\n  抽象类表示该类中可能已经有一些方法的具体定义,但是接口就仅仅只能定义各个方法的界面(方法名,参数列表,返回类型),并不关心具体细节。\r\n
 
\r\n

用法

\r\n  1)在继承抽象类时,必须覆盖该类中的每一个抽象方法,而每个已实现的方法必须和抽象类中指定的方法一样,接收相同数目和类型的参数,具有同样的返回值,这一点与接口相同。\r\n
 
\r\n  2)当父类已有实际功能的方法时,该方法在子类中可以不必实现,直接引用的方法,子类也可以重写该父类的方法(继承的概念)。\r\n
 
\r\n  3)而实现 (implement)一个接口(interface)的时候,是一定要实现接口中所定义的所有方法,而不可遗漏任何一个。\r\n
 
\r\n  4)另外,抽象类不能产生对象的,但可以由它的实现类来声明对象。\r\n
 
\r\n  有鉴于此,在实现接口时,我们也常写一个抽象类,来实现接口中的某些子类所需的通用方法,接着在编写各个子类时,即可继承该抽象类来使用,省去在每个都要实现通用的方法的困扰。\r\n
 
\r\n

实例

\r\n  为了让一个类成为抽象类,至少必须有一个纯虚函数。纯虚函数形式如下:\r\n
 
\r\n  virtual return type function() = 0;\r\n
 
\r\n  例如,类A有两个纯虚函数lock()、unlock()和一个虚析构函数:\r\n
 
\r\n  class A\r\n
 
\r\n  {\r\n
 
\r\n  public:\r\n
 
\r\n  virtual void lock(void)=0;\r\n
 
\r\n  virtual void unlock(void)=0;\r\n
 
\r\n  virtual ~A(void);\r\n
 
\r\n  }\r\n
 
\r\n  将函数lock()和unlock()初始化为0使它们成为纯虚函数,没有0这个初使化器,它们仅仅是虚函数。\r\n
 
\r\n  class B : public A\r\n
 
\r\n  {\r\n
 
\r\n  protected:\r\n
 
\r\n  pthread_mutex_t x;\r\n
 
\r\n  public:\r\n
 
\r\n  B(void);\r\n
 
\r\n  ~B(void);\r\n
 
\r\n  virtual void lock(void)\r\n
 
\r\n  {\r\n
 
\r\n  ead_mutex_lock(x);\r\n
 
\r\n  }\r\n
 
\r\n  virtual void unlock(void) {\r\n
 
\r\n  ead_mutex_unlock(x);\r\n
 
\r\n  }\r\n
 
\r\n  }\r\n
 
\r\n  抽象类对于提供模式、蓝图和后代类遵循的原则有用。如果遵循了蓝图的语义,后代类的行为可能按抽象类提供者和使用者所期望的那样。通过使用抽象类,C++程序员可以提供C++组件的规范,在它的构建中指导组件的实现者。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3012, 'java-error-1the-public-type-xxx-must-be-defined-in-its-own-file', 'Java错误1:the public type xxx must be defined in its own file.', '2012-01-17 00:58:40', '2019-03-25 21:29:22', '
作为public 类应该和文件名一致 源文件中公关类名要与文件名相同。
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3013, '%e9%86%92%e5%bf%83%e7%ae%b4%e8%a8%80', '醒心箴言', '2012-01-10 05:16:10', '2019-03-25 21:29:22', '2010年1月1日\r\n1.十年后:IT界领军人物\r\n2011年1月1日\r\n2.九年后:IT界领军人物\r\n六年后:小型创业者', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3014, 'java-override-override-the-overloaded-method-details', 'Java中重写(覆盖)与重载方法详解', '2012-01-10 02:40:26', '2019-03-25 21:29:22', 'override\r\n可以翻译为重写(覆盖),从字面就可以知道,它是覆盖了一个方法并且对其重写,以求达到不同的作用。对我们来说最熟悉的覆盖就是对接口方法的实现,在接口中一般只是对方法进行了声明,而我们在实现时,就需要实现接口声明的所有方法。除了这个典型的用法以外,我们在继承中也可能会在子类覆盖父类中的方法。在覆盖要注意以下的几点:\r\n1、覆盖的方法的标志必须要和被覆盖的方法的标志完全匹配,才能达到覆盖的效果;\r\n2、覆盖的方法的返回值必须和被覆盖的方法的返回一致;\r\n3、覆盖的方法所抛出的异常必须和被覆盖方法的所抛出的异常一致,或者是其子类;\r\n4、被覆盖的方法不能为private,否则在其子类中只是新定义了一个方法,并没有对其进行覆盖。\r\n\r\noverload\r\n对我们来说可能比较熟悉,可以翻译为重载,它是指我们可以定义一些名称相同的方法,通过定义不同的输入参数来区分这些方法,然后再调用时,VM就会根据不同的参数样式,来选择合适的方法执行。在使用重载要注意以下的几点:\r\n1、在使用重载时只能通过不同的参数样式。例如,不同的参数类型,不同的参数个数,不同的参数顺序(当然,同一方法内的几个参数类型必须不一样,例如可以是fun(int, float), 但是不能为fun(int, int));\r\n2、不能通过访问权限、返回类型、抛出的异常进行重载;\r\n3、方法的异常类型和数目不会对重载造成影响;\r\n4、对于继承来说,如果某一方法在父类中是访问权限是priavte,那么就不能在子类对其进行重载,如果定义的话,也只是定义了一个新方法,而不会达到重载的效果。\r\n\r\n下面是对override和overload的测试程序,其中注释中的内容都是会产生编译错误的代码,我们将注释去掉,看看在编译时会产生什么效果。\r\n// 对override(重写(覆盖))测试的文件:OverrideTest.java\r\npublic class OverrideTest {\r\npublic void fun() throws TestException {\r\nSystem.out.println(\"method fun in OverrideTest\");\r\n}\r\n\r\nprivate void fun1() {\r\nSystem.out.println(\"method fun1 in OverrideTest\");\r\n}\r\n\r\npublic static void main(String[] args) {\r\nOverrideTest test = new OverrideTest1();\r\ntry {\r\ntest.fun();\r\ntest.fun1();\r\n} catch(Exception e) { }\r\n}\r\n}\r\n\r\nclass OverrideTest1 extends OverrideTest{\r\n// 以下正常Override\r\npublic void fun() throws TestException2 {\r\nSystem.out.println(\"fun in OverrideTest1\");\r\n}\r\n\r\n// 不能Override父类中的方法,因为它定义了不同的异常类型和\r\n// 返回值。\r\n//public int fun() throws TestException1 {\r\n// System.out.println(\"method fun in Test\");\r\n// return 1;\r\n//}\r\n\r\n// 不能Override父类中的方法,因为它抛出了比父类中非法范围\r\n// 更大的异常。\r\n//public void fun() throws Exception {\r\n// System.out.println(\"fun in OverrideTest1\");\r\n//}\r\n\r\n// 这个方法并没有Override父类中的fun1方法,因为这个方法在\r\n// 父类是private类型,所以这里只是相当于定义了一个新方法。\r\npublic void fun1() {\r\nSystem.out.println(\"method fun1 in Test\");\r\n}\r\n}\r\n\r\nclass TestException extends Exception{\r\npublic TestException(String msg) {\r\nsuper(msg);\r\n}\r\n}\r\n\r\nclass TestException1 extends TestException {\r\npublic TestException1(String msg) {\r\nsuper(msg);\r\n}\r\n}\r\n\r\nclass TestException2 extends TestException {\r\npublic TestException2(String msg) {\r\nsuper(msg);\r\n}\r\n}\r\n\r\n// 对overload(重载)测试的文件:OverloadTest.java\r\npublic class OverloadTest {\r\n// 下面几个方法用来验证可以通过定义不同的参数类型和参数的数目进行方法重载。\r\npublic void fun(){\r\nSystem.out.println(\"method fun in OverloadTest, no parameter\");\r\n}\r\n\r\npublic void fun(float f) {\r\nSystem.out.println(\"method fun in OverloadTest, parameter type: float\");\r\n}\r\n\r\npublic void fun(int i){\r\nSystem.out.println(\"method fun in OverloadTest, parameter type: int\");\r\n}\r\n\r\npublic void fun(int i1, int i2) {\r\nSystem.out.println(\"method fun in OverloadTest, parameter type: int, int\");\r\n}\r\n\r\n// 下面的两个方法用来验证可以通过定义不同的参数顺序进行方法重载。\r\n// 需要注意:这里的参数肯定不是相同的类型,否则的顺序的先后就毫无意义。\r\npublic void fun1(int i, float f) {\r\nSystem.out.println(\"method fun1 in OverloadTest, sequence of parameters is: int, float\");\r\n}\r\n\r\npublic void fun1(float f, int i) {\r\nSystem.out.println(\"method fun1 in OverloadTest, sequence of parameters is: float, int\");\r\n}\r\n\r\n// 下面的两个方法用来验证方法抛出的异常对于重载的影响.\r\n// 无论是异常的类型还是异常的个数都不会对重载造成任何的影响。\r\npublic void fun2() throws TestException {\r\nSystem.out.println(\"fun2 in OverloadTest, exception: TestException\");\r\n}\r\n\r\npublic void fun2(int i) throws TestException, TestException1 {\r\nSystem.out.println(\"fun2 in OverloadTest, exception: TestException, TestException1\");\r\n}\r\n\r\npublic void fun2(float f) throws Exception {\r\nSystem.out.println(\"fun2 in OverloadTest, exception: Exception\");\r\n}\r\n\r\n// 不能通过抛出的异常类型来重载fun方法。\r\n//public void fun(int i) throws Exception {\r\n// System.out.println(\"method fun in OverloadTest, parameter type: int, exception: Exception\");\r\n//}\r\n\r\n// 不能通过返回值重载fun方法。\r\n//public boolean fun(int i) throws Exception {\r\n// System.out.println(\"method fun in OverloadTest, parameter type: int, exception: Exception, return: boolean\");\r\n// return true;\r\n//}\r\n\r\nprivate void fun3() { }\r\n\r\n// 不能通过不同的访问权限进行重载\r\npublic void fun3() { }\r\n\r\npublic static void main(String[] args) {\r\n// 这里只是定义了OverloadTest的实例,所以test不会调用\r\n// OverloadTest1中的方法。\r\nOverloadTest test = new OverloadTest1();\r\n// 这里定义了OverloadTest1的实例,因为OverloadTest1是OverloadTest\r\n// 的子类,所以test1会调用OverloadTest中的方法。\r\nOverloadTest1 test1 = new OverloadTest1();\r\n\r\ntry {\r\nint i = 1, j = 2, m = 3;\r\n\r\n// 这里不会调用OverloadTest1的fun方法\r\n// test.fun(i, m, j);\r\ntest1.fun(i, j, m);\r\ntest1.fun();\r\n// 这个调用不会执行,因为fun3()在OverloadTest中访问权限是priavte\r\n//test1.fun3();\r\ntest1.fun3(i);\r\n} catch(Exception e) { }\r\n}\r\n}\r\n\r\nclass OverloadTest1 extends OverloadTest{\r\n// 在子类中重载fun\r\npublic void fun(int i, int m, int n) {\r\nSystem.out.println(\"Overload fun1 in OverloadTest1, parameter type: int, int, int\");\r\n}\r\n\r\n// 这个不是对父类中方法的重载,只是一个新的方法。\r\npublic void fun3(int i) {\r\nSystem.out.println(\"fun2 in OverloadTest1\");\r\n}\r\n}\r\n\r\n ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3015, 'passing-parameters-in-java-are-value-or-reference', 'Java中参数传递是传值还是传址?', '2012-01-09 18:32:23', '2019-03-25 21:29:22', '什么是值传递?什么是引用传递?\r\n\r\n值传递是将要传递的值作为一副本传递.如\r\nint i=4;\r\nint j=i;\r\n这里相当于把4复制了一个副本给j,结果是i=4,j=4\r\n\r\n引用传递,传递的是引用对象的内存地址\r\nint *p,*p1;\r\nint j=5; *p=j; //这里是把j在内存当中的地址赋给了指针p\r\np1=p;  //这里是把指针p中保存的地址(就是j的地址)赋给了指针p1\r\nj=4; //这里改变j的值 输出结果是 j=4 , *p=4 , *p1=4 //因为p和p1指向的都是j 所以他们的值随j值改变\r\n\r\nJava中函数参数的传递是值传递还是引用传递? \r\n\r\nJava中参数传递时传递到函数中的参数都是原变量的一份拷贝,对于非类类型如int,float等,这份拷贝自然和原变量脱离了关系,这不难理解;\r\n而对于类的实例而言,这份拷贝恰巧是实例引用的拷贝,它(参数)指向的实例地址和原实例引用指向的实例地址都是一样的,因此对参数的修改有时也会影响到实例本身,故此造成了Java传递类实例是传递的引用即地址的假象,如下面例子中的changeMemberField函数,但是我们把参数指向的地址改到别的实例上时,如changeMember函数,我们会发现参数和原实例引用再也不会发生关系了,这里证明Java中参数传递是完完全全是传值而不是传址。\r\n\r\n例子代码:\r\n\r\n代码:\r\n\r\n \r\n
package com.sitinspring;public class ChangeClass{\r\npublic void changeInt(int i){\r\ni=5;\r\n}\r\n\r\npublic void changeLong(long i){\r\ni=555;\r\n}\r\n\r\npublic void changeString(String str){\r\nstr=\"5555\";\r\n}\r\n\r\npublic void changeMember(Member member){\r\nmember=new Member(\"Cindy\",35);\r\n}\r\n\r\npublic void changeMemberField(Member member){\r\nmember.setAge(20);\r\nmember.setName(\"Andy\");\r\n}\r\n\r\npublic static void main(String[] args){\r\nChangeClass changeClass=new ChangeClass();\r\n\r\nint intValue=10;\r\nchangeClass.changeInt(intValue);\r\nSystem.out.println(intValue);\r\n\r\nlong longValue=10;\r\nchangeClass.changeLong(longValue);\r\nSystem.out.println(longValue);\r\n\r\nString stringValue=\"1234\";\r\nchangeClass.changeString(stringValue);\r\nSystem.out.println(stringValue);\r\n\r\nMember member2=new Member(\"Douglas\",45);\r\nchangeClass.changeMember(member2);\r\nSystem.out.println(member2);\r\n\r\nMember member=new Member(\"Bill\",25);\r\nchangeClass.changeMemberField(member);\r\nSystem.out.println(member);\r\n}\r\n}\r\n\r\n
\r\n \r\n
package com.sitinspring;public class Member{\r\nprivate String name;\r\nprivate int age;\r\n\r\npublic Member(String name,int age){\r\nthis.age=age;\r\nthis.name=name;\r\n}\r\n\r\npublic String toString(){\r\nreturn \"Member name=\"+name+\" age=\"+age;\r\n}\r\n\r\npublic int getAge() {\r\nreturn age;\r\n}\r\n\r\npublic void setAge(int age) {\r\nthis.age = age;\r\n}\r\n\r\npublic String getName() {\r\nreturn name;\r\n}\r\n\r\npublic void setName(String name) {\r\nthis.name = name;\r\n}\r\n}
\r\n输出\r\n
10\r\n10\r\n1234\r\nMember name=Douglas age=45\r\nMember name=Andy age=20
\r\n解释:\r\n第一个输出10是因为int是基本类型,传递的参数是intValue的拷贝,对拷贝的修改对原值intValue没有影响.\r\n第一个输出10和上面是一个道理.\r\n第三个输出1234.由于String是类类型, str是stringValue的地址拷贝,参数str指向的地址和stringValue的一致,但在函数changeString 中,由于String的特殊性, str=“5555”和str=new String(“5555”)是等价的, str指向了新的”5555”所在的地址,此句后str就与原来的stringValue彻底脱离了联系.\r\n第四个输出Member name=Douglas age=45的道理和上面相同.\r\n第五个输出Member name=Andy age=20是因为changeMemberField函数中修改了参数member 的值,也就是修改member指向实例的值,而这个实例正是member指向的值,因此member就变成了name=Andy 且age=20.\r\n\r\n结论\r\n\r\nJava中参数传递的都是值,对应基本类型,传递的是原值的拷贝;对于类类型,传递的是引用即地址的拷贝.\r\n对于函数对参数的改变是否会影响原值的问题:值类型自然不会影响到原值.而对于类类型要看改变的是参数的地址还是值,如果是前者,参数和原引用指向了不同的地址,它们自然脱离了关系;如果是后者,修改的实例就是原引用指向的实例,这当然对原值进行了修改。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3016, 'regarding-the-use-of-typedefs-summary', '关于typedef的用法总结', '2012-01-08 06:36:45', '2019-03-25 21:29:22', '

不管实在C还是C++代码中,typedef这个词都不少见,当然出现频率较高的还是在C代码中。typedef与#define有些相似,但更多的是不同,特别是在一些复杂的用法上,就完全不同了。

\r\n

用途一:

\r\n

定义一种类型的别名,而不只是简单的宏替换。可以用作同时声明指针型的多个对象。比如:

\r\n

char* pa, pb; // 这多数不符合我们的意图,它只声明了一个指向字符变量的指针,

\r\n

// 和一个字符变量;

\r\n

以下则可行:

\r\n

typedef char* PCHAR;

\r\n

PCHAR pa, pb;  

\r\n

这种用法很有用,特别是char* pa, pb的定义,初学者往往认为是定义了两个字符型指针,其实不是,而用typedef char* PCHAR就不会出现这样的问题,减少了错误的发生。

\r\n

用途二:
\r\n用在旧的C代码中,帮助struct。以前的代码中,声明struct新对象时,必须要带上struct,即形式为: struct 结构名对象名,如:

\r\n

struct tagPOINT1

\r\n

 {
\r\nint x;

\r\n

    int y; 
\r\n};

\r\n

struct tagPOINT1 p1;

\r\n

而在C++中,则可以直接写:结构名对象名,即:tagPOINT1 p1;

\r\n

typedef struct tagPOINT
\r\n{
\r\nint x;

\r\n

    int y;
\r\n}POINT;

\r\n

POINT p1; // 这样就比原来的方式少写了一个struct,比较省事,尤其在大量使用的时

\r\n

候,或许,在C++中,typedef的这种用途二不是很大,但是理解了它,对掌握以前的旧代

\r\n

码还是有帮助的,毕竟我们在项目中有可能会遇到较早些年代遗留下来的代码。

\r\n

用途三:

\r\n

用typedef来定义与平台无关的类型。

\r\n

比如定义一个叫 REAL 的浮点类型,在目标平台一上,让它表示最高精度的类型为:

\r\n

typedef long double REAL;

\r\n

在不支持 long double 的平台二上,改为:

\r\n

typedef double REAL;

\r\n

在连 double 都不支持的平台三上,改为:

\r\n

typedef float REAL;

\r\n

也就是说,当跨平台时,只要改下 typedef 本身就行,不用对其他源码做任何修改。

\r\n

标准库就广泛使用了这个技巧,比如size_t。另外,因为typedef是定义了一种类型的新别名,不是简单的字符串替换,所以它比宏来得稳健。
\r\n 这个优点在我们写代码的过程中可以减少不少代码量哦!

\r\n

用途四:

\r\n

为复杂的声明定义一个新的简单的别名。方法是:在原来的声明里逐步用别名替换一部

\r\n

分复杂声明,如此循环,把带变量名的部分留到最后替换,得到的就是原声明的最简化

\r\n

版。举例: 

\r\n

 原声明:void (*b[10]) (void (*)());

\r\n

变量名为b,先替换右边部分括号里的,pFunParam为别名一:

\r\n

typedef void (*pFunParam)();

\r\n

再替换左边的变量b,pFunx为别名二:

\r\n

typedef void (*pFunx)(pFunParam);

\r\n

原声明的最简化版:

\r\n

pFunx b[10];
\r\n
\r\n原声明:doube(*)() (*e)[9];

\r\n

变量名为e,先替换左边部分,pFuny为别名一:

\r\n

typedef double(*pFuny)();

\r\n

再替换右边的变量e,pFunParamy为别名二

\r\n

typedef pFuny (*pFunParamy)[9];

\r\n

原声明的最简化版:

\r\n

pFunParamy e;

\r\n

理解复杂声明可用的“右左法则”:从变量名看起,先往右,再往左,碰到一个圆括号

\r\n

就调转阅读的方向;括号内分析完就跳出括号,还是按先右后左的顺序,如此循环,直

\r\n

到整个声明分析完。举例:

\r\n

int (*func)(int *p);

\r\n

首先找到变量名func,外面有一对圆括号,而且左边是一个*号,这说明func是一个指针

\r\n

;然后跳出这个圆括号,先看右边,又遇到圆括号,这说明(*func)是一个函数,所以

\r\n

func是一个指向这类函数的指针,即函数指针,这类函数具有int*类型的形参,返回值

\r\n

类型是int。

\r\n

int (*func[5])(int *);

\r\n

func右边是一个[]运算符,说明func是具有5个元素的数组;func的左边有一个*,说明

\r\n

func的元素是指针(注意这里的*不是修饰func,而是修饰func[5]的,原因是[]运算符

\r\n

优先级比*高,func先跟[]结合)。跳出这个括号,看右边,又遇到圆括号,说明func数

\r\n

组的元素是函数类型的指针,它指向的函数具有int*类型的形参,返回值类型为int。

\r\n

这种用法是比较复杂的,出现的频率也不少,往往在看到这样的用法却不能理解,相信以上的解释能有所帮助。

\r\n

使用示例:

\r\n

1.比较一:

\r\n

#include <iostream>

\r\n

using namespace std;

\r\n

typedef int (*A) (char, char);

\r\n

int ss(char a, char b)
\r\n{
\r\ncout<<\"功能1\"<<endl;

\r\n

    cout<<a<<endl;

\r\n

    cout<<b<<endl;

\r\n

    return 0;
\r\n}
\r\n
\r\nint bb(char a, char b)
\r\n{

\r\n

    cout<<\"功能2\"<<endl;

\r\n

    cout<<b<<endl;

\r\n

    cout<<a<<endl;

\r\n

    return 0;

\r\n

}

\r\n

void main()
\r\n{

\r\n

    A a;

\r\n

    a = ss;

\r\n

    a(\'a\',\'b\');

\r\n

    a = bb;

\r\n

    a(\'a\', \'b\');
\r\n}

\r\n

2.比较二:

\r\n

typedef int (A) (char, char);

\r\n

void main()
\r\n{

\r\n

    A *a;

\r\n

    a = ss;

\r\n

    a(\'a\',\'b\');

\r\n

    a = bb;

\r\n

    a(\'a\',\'b\');
\r\n}
\r\n

\r\n

两个程序的结果都一样:

\r\n

功能1

\r\n

a

\r\n

b

\r\n

功能2

\r\n

b

\r\n

a

\r\n

 

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3017, '%e4%ba%ba%e7%94%9f%e5%b0%8f%e6%82%9f', '人生小悟', '2012-01-08 06:08:59', '2019-03-25 21:29:22', '1.大学,是否有成就,取决于醒悟的早晚,醒悟的程度,醒悟的方向,记住:机会总是留给有准备的人。2012/01/08\r\n2.忽略表面的浮华,追求深层的高度,这是你走向有品位的人的开始。2011/01/09', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3018, 'classical-view-only-volume-5-lived-qin', '《古文观止》卷六 5.过秦论上', '2012-01-08 05:40:50', '2019-03-25 21:29:22', '

[copy]classical-view-only-volume-5-lived-qin[/copy]

\r\n

[youku]XMjQ2MDY4MjI0[/youku]

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3020, 'tomcat-error-solution-1the-apr-based-apache-tomcat-native-library-which-allows-optimal-performance-in-production-environments-was-not-found-on-the-java-library-path', 'Tomcat错误解决方案1:The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path', '2012-01-07 20:11:20', '2019-03-25 21:29:22', '错误提示:\r\n2011-5-6 12:08:43 org.apache.catalina.core.AprLifecycleListener init\r\n信息: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: D:Program FilesMyEclipseCommonbinarycom.sun.java.jdk.win32.x86_1.6.0.013bin;D:Tomcat 7.0bin\r\n\r\n解决方案:\r\n1.关闭Tomcat服务器\r\n2.下载tcnative-1.dll\r\nhttp://archive.apache.org/dist/tomcat/tomcat-connectors/native\r\n3.将它放到Tomcatbin下面\r\n4.重启Tomcat服务器。\r\n\r\n解决后:\r\n2011-5-6 12:10:37 org.apache.catalina.core.AprLifecycleListener init\r\n信息: Loaded APR based Apache Tomcat Native library 1.1.22.\r\n2011-5-6 12:10:37 org.apache.catalina.core.AprLifecycleListener init\r\n信息: APR capabilities: IPv6 [false], sendfile [true], accept filters [false], random [true].\r\n2011-5-6 12:10:47 org.apache.coyote.AbstractProtocol init\r\n信息: Initializing ProtocolHandler [\"http-apr-8080\"]\r\n2011-5-6 12:10:47 org.apache.coyote.AbstractProtocol init\r\n信息: Initializing ProtocolHandler [\"ajp-apr-8009\"]\r\n2011-5-6 12:10:47 org.apache.catalina.startup.Catalina load\r\n信息: Initialization processed in 10447 ms\r\n2011-5-6 12:10:48 org.apache.catalina.core.StandardService startInternal\r\n信息: Starting service Catalina\r\n2011-5-6 12:10:48 org.apache.catalina.core.StandardEngine startInternal\r\n信息: Starting Servlet Engine: Apache Tomcat/7.0.22\r\n2011-5-6 12:10:48 org.apache.catalina.startup.HostConfig deployDirectory\r\n信息: Deploying web application directory ROOT\r\n2011-5-6 12:10:48 org.apache.catalina.startup.HostConfig deployDirectory\r\n信息: Deploying web application directory docs\r\n2011-5-6 12:10:48 org.apache.catalina.startup.HostConfig deployDirectory\r\n信息: Deploying web application directory manager\r\n2011-5-6 12:10:48 org.apache.catalina.startup.HostConfig deployDirectory\r\n信息: Deploying web application directory host-manager\r\n2011-5-6 12:10:48 org.apache.catalina.startup.HostConfig deployDirectory\r\n信息: Deploying web application directory examples\r\n2011-5-6 12:10:49 org.apache.catalina.core.ApplicationContext log\r\n信息: ContextListener: contextInitialized()\r\n2011-5-6 12:10:49 org.apache.catalina.core.ApplicationContext log\r\n信息: SessionListener: contextInitialized()\r\n2011-5-6 12:10:49 org.apache.catalina.core.ApplicationContext log\r\n信息: ContextListener: attributeAdded(\'org.apache.jasper.compiler.TldLocationsCache\', \'org.apache.jasper.compiler.TldLocationsCache@1abfbdc\')\r\n2011-5-6 12:10:49 org.apache.coyote.AbstractProtocol start\r\n信息: Starting ProtocolHandler [\"http-apr-8080\"]\r\n2011-5-6 12:10:49 org.apache.coyote.AbstractProtocol start\r\n信息: Starting ProtocolHandler [\"ajp-apr-8009\"]\r\n2011-5-6 12:10:49 org.apache.catalina.startup.Catalina start\r\n信息: Server startup in 1167 ms', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3021, 'mathtype-6-7-english-version', 'MathType 6.7 英文版', '2012-01-01 22:16:35', '2019-03-25 21:29:22', '软件截图:\r\n\"\"\r\n安全认证:\r\n\"360认证\"360通过 \"金山认证\"金山通过\"瑞星认证\"瑞星通过\"卡巴认证\"卡巴通过\r\n\"小红伞认证\"小红伞通过\"NOD认证\"NOd通过\"无插件\"无插件\"win7兼容\"win7兼容\r\n\"新价值认证\"\r\n软件大小6.0MB\r\n下载次数:13100144 \r\n软件授权:注册软件\r\n软件语言:英文\r\n开 发 商:http://www.dessci.com/en/products/mathtype/default.htm\r\n评价等级:\"\"\r\n

更新时间:2012-01-01 19:47:56

\r\n应用平台:Win7/Vista/Win2003/WinXP/Win2000/\r\n软件介绍:MathType 是一个由美国Design Science公司开发的强大的数学公式编辑器,它同时支持WindowsMacintosh 操作系统,与常见的文字处理软件和演示程序配合使用,能够在各种文档中加入复杂的数学公式和符号。MathType 6.0c 与常见文字处理工具紧密结合,支持 OLE (对象的链接与嵌入),可以在任何支持 OLE 的文字处理系统中调用 (从主菜单中选择 \"插入->对象\" 在新对象中选择 \"MathType 6.0 Equation\" ),帮助用户快速建立专业化的数学技术文档。\r\n\r\n新价值网提醒您:MathType 6.7 30 天试用版软件,如需要购买正式版序列号。\r\n下载地址:\"电信下载\"   \r\n\r\n \r\n
\r\n ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3022, 'banquet-concubine-song-sung-by-chu-come-rain-in-mongolia', '《鸿门宴》虞姬所唱楚曲-烟雨蒙兮', '2012-01-01 07:13:54', '2019-08-24 13:28:59', '

[copy]banquet-concubine-song-sung-by-chu-come-rain-in-mongolia[/copy] [youku]XMzc5MTk3OTk2[/youku]

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3025, 'microspft-sql-server-2008-r2-is-chinese-simplified-version', 'Microspft Sql Server 2008 R2简体中文版', '2011-12-30 07:09:07', '2019-03-25 21:29:22', '
软件截图:\r\n\"\"\r\n安全认证:\r\n\"360认证\"360通过 \"金山认证\"金山通过\"瑞星认证\"瑞星通过\"卡巴认证\"卡巴通过\r\n\"小红伞认证\"小红伞通过\"NOD认证\"NOd通过\"无插件\"无插件\"win7兼容\"win7兼容\r\n\"新价值认证\"\r\n软件大小1.46 GB\r\n下载次数:13100144 \r\n软件授权:注册软件\r\n软件语言:简体中文\r\n开 发 商:http://www.mocrosoft.com/\r\n评价等级:\"\"\r\n

更新时间:2011-12-29 19:47:56

\r\n应用平台:Win7/Vista/Win2003/WinXP/Win2000/\r\n软件介绍:SQL Server 2008 R2新增了大量重要功能,在性能和可扩展性方面也有了极大提升。主要功能包括:\r\nPowerPivot:\r\n这是一种自主托管分析方案,帮助终端用户在IT管理环境中使用Excel 2010和SharePoint 2010访问、分析和共享企业数据。\r\n主数据服务:\r\n帮助IT组织实现中央管理全公司及跨系统的重要数据资产,允许更多用户安全地直接管理主数据。\r\n应用程序和多服务器管理:\r\n帮助企业前摄地管理数据库环境。\r\nReport Builder 3.0\r\nStreamInsight\r\n其主要特性包括:\r\n实用性高的可信赖和可扩展平台,主数据服务支持异构系统间的数据协调,StreamInsight能够实现对大规模复杂事件的处理,并支持多达256个逻辑处理器的大型应用程序。\r\n通过对多种数据库应用程序、实例或服务器的集中管理提高IT和开发人员的效率,加快应用程序的开发和部署,通过 Windows Server 2008 R2中的Hyper-V来完善对虚拟化和实时迁移的支持。\r\n可托管的自助式商业智能(self-service business intelligence)赋予企业用户在无IT支持的情况下创建并分享强大的商业智能(BI)方案的能力,同时还可以使用Excel和 SharePoint中最新的PowerPivot技术监控和管理终端用户生成的BI方案。\r\n拥有软件保障(Software Assurance)的客户可以升级至SQL Server 2008 R2,无需任何额外授权费用即可使用其新增功能。\r\nMicrosoft SQL Server 2008安装说明:\r\n\r\n1、请点击进入网盘后,再进行相关下载。\r\n2、下载完成后运行“SQLFULL_x86_CHS.exe”,选择解压的路径开始解压文件。\r\n3、解压完成后,运行解压目录中的“setup.exe”进行安装。\r\n\r\n新价值网提醒您:SQL Server 2008 R2是180 天试用版软件,如需要购买正式版序列号。\r\n下载地址:\"电信下载\"   \r\n\r\n
\r\n \r\n
\r\n ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3026, 'collection-of-classic-java-program-code', 'Java经典程序代码集锦', '2011-12-27 05:09:51', '2019-03-25 21:29:22', '
1.求质数(更新于2011/12/12)
\r\n2.冒泡法排序(更新于2011/12/26)\r\n3.选择法排序(更新于2011/12/26)\r\n4.二分法查找(更新于2012/04/22)\r\n更新中,敬请期待。。。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3027, 'java-sort', 'Java实现冒泡法排序与选择法排序', '2011-12-27 04:43:05', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

  1. public class Main {  
  2.     public static void BubbleSort(int[] a)// 冒泡排序  
  3.     {  
  4.         int i, j;  
  5.         for (i = 0; i < a.length - 1; i++)  
  6.             for (j = 0; j < a.length - i - 1; j++) {  
  7.                 if (a[j] > a[j + 1]) {  
  8.                     int temp;  
  9.                     temp = a[j];  
  10.                     a[j] = a[j + 1];  
  11.                     a[j + 1] = temp;  
  12.                 }  
  13.             }  
  14.     }  
  15.  
  16.     public static void SelectionSort(int[] a)// 选择排序  
  17.     {  
  18.         int i, j;  
  19.         for (i = 0; i < a.length; i++)  
  20.             for (j = i + 1; j < a.length; j++) {  
  21.                 if (a[i] > a[j]) {  
  22.                     int temp;  
  23.                     temp = a[i];  
  24.                     a[i] = a[j];  
  25.                     a[j] = temp;  
  26.                 }  
  27.             }  
  28.     }  
  29.  
  30.     public static void main(String[] args) {  
  31.         int[] a = new int[]{5, 8, 9, 6, 7};  
  32.         // BubbleSort(a);//调用冒泡排序  
  33.         SelectionSort(a);// 调用选择排序  
  34.         for (int i = 0; i < a.length; i++) {  
  35.             System.out.println(a[i]);  
  36.         }  
  37.  
  38.     }  
  39. }  
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3028, 'glassfish-and-javaee-tomcat-deployment-walkthrough', 'GlassFish和Tomcat部署JavaEE详解', '2011-12-19 02:10:42', '2019-03-25 21:29:22', '1.在Glassfish上部署web实际运用 \r\n\r\n一,开发道具的选取\r\n\r\nJava EE,或者是JSF实际运用开发,Netbeans和Glassfish是最好的搭配选取,前者对于后者有非比寻常好的支持。但要留意netbeans的 版本,5.5是不支持glassfish v2的。而netbeans6还很不稳定,所以现阶段最好的版本是netbeans5.5.1。\r\n\r\n涉及Netbeans下开发Java EE实际运用,官方有文档介绍:Java EE 实际运用程序有关教程,那里主要介绍一下生产环境中web实际运用在glassfish下的部署和配置\r\n

二,下载安装Glassfish V2

\r\n

1)下载并解压缩。下载完毕後,运行以下命令:

\r\n

java -Xmx256m -jar glassfish_filetitle.jar

\r\n

点击接受弹出的规则后(那里sun较量无聊啊,所有软件 都是,明明一个的普通压缩包,非压成jar让你看一下规则才行),glassfish会解压到一个的名为glassfish的列表里。\r\n2) 改正端口

\r\n

glassfish是经过ant来安装的,安装脚本在setup.xml下,在里面没成绩改正一些配置,比如端口等等。在setup.xml中主要有以下设置:

\r\n

xml 源代码

\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
﹤property title=\"domain.title\" value=\"domain1\"/﹥ 域名\r\n﹤property title=\"instance.title\" value=\"server\"/﹥\r\n﹤property title=\"admin.user\" value=\"admin\"/﹥ 编程用户名\r\n﹤property title=\"admin.passexpress\" value=\"adminadmin\"/﹥ 编程密码\r\n﹤property title=\"admin.port\" value=\"4848\"/﹥ 管理平台端口\r\n﹤property title=\"instance.port\" value=\"8080\"/﹥ 举例端口,也那是经过那个端口来访问web实际运用\r\n﹤property title=\"orb.port\" value=\"3700\"/﹥\r\n﹤property title=\"imq.port\" value=\"7676\"/﹥\r\n﹤property title=\"https.port\" value=\"8181\"/﹥ https端口
\r\n

根据需求改正以上设置,运行:ant -f setup.xml,假如系统没有安装ant,在glassfishlibant下有一个的ant1.6版。安装结束后,进入glassfish/bin下,在控制台运行下面命令启动glassfish:

\r\n

asadmin start-domain domain1 // domain1是上面设置的domain.title,系统默认domain1

\r\n

启动结束后,进入测试也许已经正确启动

\r\n

asadmin stop-domain domain1 //停止服务器\r\n三,部署web实际运用

\r\n

有三种方法,第一是直接将war或ear放在glassfish/domain/autodeploy列表 下,glassfish启动后会自动部署。第二是经过命令asadmin deploy部署实际运用, 另外 asadmin updeploy 卸载实际运用。经过asadmin deploy --help 和 asadmin undeploy --help 获得更多帮助。

\r\n

第三是经过我推荐的方法,经过glassfish管理控制台进入,默认用户admin,密码adminadmin。打开後看到如下界面:

\r\n

进入左边菜单, Applications -> Web Applications,在列表中没成绩看到已经部署的实际运用,如要部署新实际运用,点击deploy按钮,选取本地的war,设定好context path,点击OK,无论部署胜利或失败,都会看到相应的消息提示

\r\n

注:经过这种方法,没成绩停止远程部署,只要打开目的服务器上的管理控制台,选取一个的本地的war,就没成绩快速的部署到远程服务器上,非比寻常方便,这也是推荐的理由。对于EJB实际运用,在Enterprise Applications下部署,窍门同上

\r\n

四,配置jdbc数据源

\r\n

对于Java EE实际运用,经常需求事先设定数据源,否则部署时会报javax.naming.NameNotFoundException

\r\n

配置窍门是进入Resources -> JDBC,会看到JDBC Resources和Connection pools

\r\n

先设定Connection pools,以MySql为例,点击New,命名为MySqlPools,ResourceType选取 javax.sql.ConnectionPoolDataSource,Database vendor肯定选取mysql,然后点击beside进入下一页面。最主要的是设定Additional Properties,也那是jdbc连接配置,设定好url, user, passexpress,更多相关的保持默认value,也没成绩根据需求自己添加属性。设定好连接池后,接着设定JDBC Resources,新建一个的JDBC,名称要和你的web实际运用里的持久化单元采用的数据源的名称一致。\r\n然后再次部署web实际运用,就会正常运行了。

\r\n2.在Tomcat中部署Java Web应用程序(jar命令打war包)\r\n本文的重点是如何部署,所以暂且先不介绍怎样开发Web应用程序和怎样启动Tomcat服务器,也不考虑使用的什么开发工具,总之在练习本文所说的例子之前,你应该有一个Java Web应用程序。本文假定Web应用程序的根目录为PetWeb。而且存放在F:下。下文中$CATALINA_HOME指的是Tomcat根目录。\r\n\r\n在Tomcat中部署Java Web应用程序有两种方式:静态部署和动态部署。\r\n一、静态部署\r\n静态部署指的是我们在服务器启动之前部署我们的程序,只有当服务器启动之后,我们的Web应用程序才能访问。以下3中方式都可以部署:\r\n1、将PetWeb目录拷贝到$CATALINA_HOMEwebapps下,然后启动服务器就可以了。这种方式比较简单,访问地址如下:http://localhost:8080/PetWeb/\r\n2、这种方式可以不必将PetWeb目录拷贝到webapps下,直接在F:部署。方法如下,更改$CATALINA_HOMEconfserver.xml文件,在<host>标签内添加<Context>标签,内容如下:\r\n<Context docBase=\"F:/PetWeb\" reloadable=\"false\" path=\"/Pet\"/>\r\n其中reloadable=\"false\"表示当应用程序中的内容发生更改之后服务器不会自动加载,这个属性在开发阶段通常都设为true,方便开发,在发布阶段应该设置为false,提高应用程序的访问速度。docBase为路径,可以使用绝对路径,也可以使用相对路径,相对路径相对于webapps。 path属性的值是访问时的根地址。访问地址如下:http://localhost:8080/Pet/\r\n3、这种方式和第二种方式差不多,但是不是在Server.xml文件中添加Context标签,而是在$CATALINA_HOMEconfCatalinalocalhost中添加一个xml文件,如Pet.xml,内容如下:\r\n<Context docBase=\"F:/PetWeb\" reloadable=\"false\" />大家可能发现和第二种方式差不多,但是缺少了path属性,这种方式服务器会使用.xml的名字作为path属性的值。访问地址如下:http://localhost:8080/Pet/\r\n\r\n我们刚才是将PetWeb文件夹部署在了服务器中,我们知道可以将Web应用程序的内容打成.war包,然后在部署在服务器上。打包请参考如下步骤:\r\n1、打开命令提示符(Start-->Run-->cmd)\r\n2、设置jdk环境变量(如果我教过的学生不会配置,以后别说孙老师教过你)\r\n3、在命令提示符中进入F:PetWeb文件后,键入如下命令:\r\njar cvf Pet.war */. 应这样在当前目录下该有Pet.war文件。其中..表示当前目录的父目录。\r\n部署Pet.war文件非常简单,将刚才有docBase=\"F:PetWeb\"更改为docBase=\"F:Pet.war\"或者直接将其拷贝到 webapps下也可以。重新启动服务器就可以将Pet.war部署为一个Web应用程序了。如果你够细心的话你会发现,服务器将Pet.war文件解开,并且在webapps下面又生成了一个Pet文件夹,然后把Pet.war的内容拷贝到里面去了。我们可以通过以下方式取消自动解包,配置方式如下:\r\n<Context docBase=\"F:/PetWeb\" reloadable=\"false\" unpackWAR=\"false\"/>\r\n\r\n二、动态部署\r\n动态部署是指可以在服务器启动之后部署web应用程序,而不用重新启动服务器。动态部署要用到服务器提供的manager.war文件,如果在$CATALINA_HOMEwebapps下没有该文件,你必须去重新下载tomcat,否则不能完成以下的功能。要想使用该管理程序必须首先编辑$CATALINA_HOMEconftomcat-users.xml文件,内容如下:\r\n<tomcat-users>\r\n<role rolename=\"tomcat\"/>\r\n<role rolename=\"role1\"/>\r\n<role rolename=\"manager\"/>\r\n<user username=\"coresun\" password=\"coresun\" roles=\"manager\"/>\r\n<user username=\"tomcat\" password=\"tomcat\" roles=\"tomcat\"/>\r\n<user username=\"both\" password=\"tomcat\" roles=\"tomcat,role1\"/>\r\n<user username=\"role1\" password=\"tomcat\" roles=\"role1\"/>\r\n</tomcat-users>\r\n然后在浏览器中键入如下地址:\r\nhttp://localhost:8080/应该看到一个漂亮的加菲猫了吧。点击左边的Tomcat Manager链接,提示输入用户名和密码,本文都是coresun,然后可以看到以下页面:\r\n\"\"在Context Path(option):中输入/Pet\r\nXML Configration file URL中要指定一个.xml文件,比如我们在F:下建立一个Pet.xml文件,内容如下:\r\n<Context reloadable=\"false\" />docBase不用写了,因为在下一个文本框中填入。或者更简单点,这个文本框什么都不填。\r\n在WAR or Directory URL:中键入F:PetWet或者F:Pet.war都可以,然后点击Deploy按钮,看看上面是不是已经看到了你web应用程序,名字就是你Context Path(option):中的名字。\r\n\r\n如果你部署.war文件还有更加简单的方式,下面还有个Select WAR file uploae点击浏览选择.war文件,然后点击Deploy也可以。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3029, 'tomcat7w-exe-tomcat7-exe-tip-the-specified-service-is-unable-to-open-the-service-is-not-installed-tomcat7', '运行tomcat7w.exe tomcat7.exe ,提示:指定的服务未安装 unable to open the service 'tomcat7'', '2011-12-18 23:42:36', '2019-03-25 21:29:22', '问题描述:\r\n运行tomcat7w.exe tomcat7.exe ,提示 指定的服务未安装 unable to open the service \'tomcat7\'(用的是绿色的Tomcat7)\r\n\r\n解决方法:\r\n打开命令行提示符窗口=> 进入Tomcat安装目录==> 进入bin目录下==> 输入:service.bat install 即可\r\n

\"\"

\r\n

      直接到目录点击这个service.bat会不会也可以?经过验证:不可以

\r\n \r\n
\r\n
 
\r\n
\r\n ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3030, 'jsp-web-infmeta-inf-files-in-your-project-details', 'JSP项目中的WEB-INF,META-INF文件详解', '2011-12-18 09:32:27', '2019-03-25 21:29:22', '\r\n\r\n\r\n\r\n\r\n\r\n
\r\n
WEB-INF/WEB-INF/web.xml\r\n你的Web应用程序配置文件,这是一个XML文件,其中描述了 servlet 和其他的应用组件配置及命名规则;\r\n\r\n/WEB- INF/classes/\r\n这个目录包含了站点所有用的 class 文件,包括 servlet class 和非servlet class,他们不能包含在 .jar文件中。\r\n站点的类的存放规则应该按照Java的打包规则执行。例如: 有一个类命名为 com.mycompany.mypackage.MyServlet, 你应该按照以下形式部署: /WEB-INF/classes/com /mycompany/mypackage/MyServlet.class ;\r\n按照包名结构放置各个类(JavaBean 和 Servlet)\r\n\r\n/WEB- INF/lib/\r\n存放web应用需要的各种JAR文件,放置仅在这个应用中要求使用的jar文件,如数据库驱动jar文件\r\n\r\n/WEB- INF/src/\r\nsrc=source 源码目录,按照包名结构放置各个java文件\r\n\r\n/WEB- INF/database.properties\r\n数据库配置文件\r\n# database.properties\r\njdbc.drivers = com.mysql.jdbc.Driver\r\njdbc.url = jdbc:mysql://localhost/ams2\r\njdbc.username = root\r\njdbc.password = sh2007ai\r\n\r\n# table define\r\nams2.table.dialogue = content_dialogue\r\nams2.table.expansion = content_expansion_sentence\r\nams2.table.vocabulary = content_vocabulary\r\n\r\n/WEB-INF/tags/\r\n标签文件库,存放了客户定义的标签文件,该目录并不一定为 tags,用户可以根据自己的喜好和习惯为自己的标签文件库命名,当使用了用户定义的标签文件库名称时,在用户使用标签文件时就必须声明正确的标签文件库路径。例如:当自定义标签文件库名称为 simpleTags 时,在使用 simpleTags 目录下的标签文件时,就必须在 jsp 文件头声明为:<%@ taglib prefix=\"tags\" tagdir=\"/WEB-INF /simpleTags\" % >;\r\n\r\n/WEB-INF/jsp/\r\nJsp 1.2 以下版本的文件存放位置。改目录没有特定的声明,同样,用户可以根据自己的喜好与习惯来命名。此目录主要存放的是 Jsp 1.2 以下版本的文件,为区分 Jsp 2.0 文件,通常使用 jsp 命名,当然你也可以命名为 jspOldEdition ;\r\n\r\n/WEB-INF/jsp2/\r\n与 jsp 文件目录相比,该目录下主要存放 Jsp 2.0 以下版本的文件,当然,它也是可以任意命名的,同样为区别 Jsp 1.2 以下版本的文件目录,通常才命名为 jsp2。\r\n\r\nMETA-INF\r\n\r\n相当于一个信息包,目录中的文件和目录获得Java 2平台的认可与解释,\r\n\r\n用来配置应用程序、扩展程序、类加载器和服务\r\nmanifest.mf文件,在用jar打包时自动生成
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3031, 'create-a-sqlite-database-under-windows', 'windows下创建sqlite数据库', '2011-12-16 19:56:36', '2019-03-25 21:29:22', '      今天在网上下载了一个SQLite3,本以为是个轻量级的数据库,很容易使用,但是第一步让我晕了很久,终于搞出来了。\r\n关于SQLite3的使用:\r\n1.将sqlite3.exe文件放在任何位置(本人放在E:Sqlite)\r\n2.在CMD下进入到E:Sqlite下\r\n3.在CMD命令提示符下输入sqlite3.exe php.db(php.db是数据库名)回车\r\n\"\"\r\n注意:这时php.db数据库确实已经创建好了,但是还是一个临时的,所以现在要输入SQL命令\r\n4.create table user(name text);\r\n5.这时,再到E:Sqlite下查看,生成了一个php.db文件,这就是我们要创建的数据库\r\n\"\"\r\n6.如果下次还要使用此数据库时,仍然使用sqlite3.exe php.db即可进入此数据库;\r\n7.其它问题可以查看DOC和.help。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3032, 'php-website-installation-database-error-allowed-memory-size-of-8388608-bytes-exhausted-solution', 'php网站安装数据库错误:Allowed memory size of 8388608 bytes exhausted解决方法', '2011-12-16 07:30:00', '2019-03-25 21:29:22', '出现该错误的原因:\r\n\r\n    是因为php页面消耗的最大内存默认是为 8M (在PHP的ini件里可以看到) ,如果文件太大 或图片太大 在读取的时候 会发生上述错误。\r\n\r\n解决办法:\r\n\r\n    1,修改 php.ini\r\n将memory_limit由 8M 改成 16M(或更大),重启apache服务\r\n\r\n    2,在PHP 文件中 加入 ini_set(”memory_limit”,”100M”);\r\n\r\n注意:为了系统的其它资源的正常使用 请您不要将 memory_limit设置太大,其中-1为不限\r\n\r\n    3,修改.htaccess 文档(前提是该目录支持.htaccess)\r\n在文档中新增一句:php_value memory_limit 16M(或更大)', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3033, 'phpmyadmin-error-solved-2002-no-response-from-the-server-or-the-local-mysql-servers-socket-is-not-correctly-configured', 'phpMyAdmin错误解决:#2002 – 服务器没有响应 (或者本地 MySQL 服务器的套接字没有正确配置)', '2011-12-16 07:17:43', '2019-03-25 21:29:22', '    安装了Apache,因为测试PHP网站需要MySQL,所以就安装了MySQL,但是由于对MySQL数据库不太熟悉,于是下载了phpMyAdmin来管理数据库。\r\n\r\n    将phpMyAdmin解压到Apache的PHP网站目录下,并找到libraries/config.default.php复制到phpMyAdmin目录下并改成config.inc.php,然后输入网址登录,却提示#2002 – 服务器没有响应,后来从网上查了很多方法都没法登录,而且有时候还会显示#2002 – 服务器没有响应 (或者本地 MySQL 服务器的套接字没有正确配置)。\r\n\r\n    后来终于找到了一个原因,竟然是MySQL数据库服务器的地址应该改成127.0.0.1,具体方法:\r\n\r\n    打开我们刚才拷贝到phpMyAdmin目录下的config.inc.php 中\r\n\r\n    找到这句话:$cfg[\'Servers\'][$i][\'host\'] = \'localhost\';\r\n\r\n    改成 $cfg[\'Servers\'][$i][\'host\'] = \'127.0.0.1\';\r\n\r\n    这样就可以了……\r\n\r\n ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3035, 'insert-a-text-box-template', '插入文本框模版', '2011-12-13 00:54:26', '2019-03-25 21:29:22', '效果:\r\n
\r\n
\r\n代码:\r\n
\r\n\r\n <div style=\"border-bottom: rgb(204,204,204) 1px solid; border-left: rgb(204,204,204) 1px solid; padding-bottom: 4px; background-color: rgb(238,238,238); padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: rgb(204,204,204) 1px solid; border-right: rgb(204,204,204) 1px solid; padding-top: 4px\">\r\n

 <br />

\r\n

 &nbsp;</div>

\r\n\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3036, 'java-applets-1-the-perfect-algorithm-for-finding-prime-numbers', 'Java小程序1:求质数的完美算法', '2011-12-12 21:01:27', '2019-03-25 21:29:22', '
\r\n

\r\npublicclass MyMethod

\r\n

\r\n{

\r\n

\r\n    publicstaticvoid Prime(int end)

\r\n

\r\n    {

\r\n

\r\n        if (end <= 0)

\r\n

\r\n        {

\r\n

\r\n            end = -end;

\r\n

\r\n            System.out.println((-end) + \"-1\" + \"之间的所有质数为:\");

\r\n

\r\n            for (int i = 2; i <= end; i++)

\r\n

\r\n            {

\r\n

\r\n                 int k;

\r\n

\r\n                 for (k = 2; k <= i; k++)

\r\n

\r\n                {// k小于i,并且大于n

\r\n

\r\n                    if (i % k == 0)

\r\n

\r\n                    {

\r\n

\r\n                        break;// 如果i能被除1和本身的数整除,跳出循环。

\r\n

\r\n                    }

\r\n

\r\n                }

\r\n

\r\n                if (i == k)

\r\n

\r\n                    System.out.println(-i);// 输出质数

\r\n

\r\n            }

\r\n

\r\n        }

\r\n

\r\n        else

\r\n

\r\n        {

\r\n

\r\n            System.out.println(\"1\" + end + \"之间的所有质数为:\");

\r\n

\r\n            for (int i = 2; i <= end; i++)

\r\n

\r\n            {

\r\n

\r\n                int k;

\r\n

\r\n                for (k = 2; k <= i; k++)

\r\n

\r\n                {// k小于i,并且大于n

\r\n

\r\n                   if (i % k == 0)

\r\n

\r\n                    {

\r\n

\r\n                        break;// 如果i能被除1和本身的数整除,跳出循环。

\r\n

\r\n                   }

\r\n

\r\n                }

\r\n

\r\n                if (i == k)

\r\n

\r\n                    System.out.println(i);// 输出质数

\r\n

\r\n            }

\r\n

\r\n        }

\r\n

\r\n    }

\r\n

\r\n 

\r\n

\r\n    publicstaticvoid main(String[] args)

\r\n

\r\n    {

\r\n

\r\n        int end = 100;

\r\n

\r\n        Prime(end);

\r\n

\r\n    }

\r\n

\r\n}

\r\n

 

\r\n\r\n
\r\n\"\"', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3038, 'html-special-characters-display', 'HTML特殊字符显示', '2011-12-10 04:39:09', '2019-03-25 21:29:22', '

HTML字符实体(Character Entities)

\r\n有些字符在HTML里有特别的含义,比如小于号<就表示HTML Tag的开始,这个小于号是不显示在我们最终看到的网页里的。那如果我们希望在网页中显示一个小于号,该怎么办呢?\r\n\r\n这就要说到HTML字符实体(HTML Character Entities)了。\r\n\r\n一个字符实体(Character Entity)分成三部分:第一部分是一个&符号,英文叫ampersand;第二部分是实体(Entity)名字或者是#加上实体(Entity)编号;第三部分是一个分号。\r\n\r\n比如,要显示小于号,就可以写&lt;或者&#60;。\r\n\r\n用实体(Entity)名字的好处是比较好理解,一看lt,大概就猜出是less than的意思,但是其劣势在于并不是所有的浏览器都支持最新的Entity名字。而实体(Entity)编号,各种浏览器都能处理。\r\n\r\n注意:Entity是区分大小写的。\r\n

如何显示空格

\r\n通常情况下,HTML会自动截去多余的空格。不管你加多少空格,都被看做一个空格。比如你在两个字之间加了10个空格,HTML会截去9个空格,只保留一个。为了在网页中增加空格,你可以使用&nbsp;表示空格。\r\n

最常用的字符实体(Character Entities)

\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
显示结果说明Entity NameEntity Number
显示一个空格&nbsp;&#160;
<小于&lt;&#60;
>大于&gt;&#62;
&&符号&amp;&#38;
\"双引号&quot;&#34;
\r\n

其他常用的字符实体(Character Entities)

\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
显示结果说明Entity NameEntity Number
©版权&copy;&#169;
®注册商标&reg;&#174;
×乘号&times;&#215;
÷除号&divide;&#247;
\r\n

更多字符实体(Character Entities)

\r\n更多字符实体(Character Entities)请参见 ISO Latin-1字符集', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3039, 'difference-between-web-page-th-and-td', '网页中th与td的区别', '2011-12-10 03:47:29', '2019-03-25 21:29:22', '<TH>与<TD>同样是标示一个储存格,唯一不同的是<TH>所标示的储存格中的文字是以粗体出现,即可以这样看:\r\n<th>文字</th>=<td><b>文字</b></td>\r\n\r\n<table>是<tr>的上层标签\r\n<tr>必须在一个<table></table>里面,它不能单独使用,相当于<table>的属性标签.\r\n<table>标示一个表格,<tr>标示这个表格中间的一个行\r\n<td>标示行中的一个列,需要嵌套在<tr></tr>中间\r\n\r\n具体格式是:(两行两列)\r\n<table>\r\n<tr>\r\n<td></td>\r\n<td></td>\r\n</tr>\r\n<tr>\r\n<td></td>\r\n<td></td>\r\n</tr>\r\n</teble>\r\n\r\n补充:\r\n<th>和<td>一样,也是需要嵌套在<tr>当中的,<tr>嵌套在<table>当中\r\n\r\n<table>...</table> 用于定义一个表格开始和结束\r\n\r\n<th>...</th> 定义表头单元格。表格中的文字将以粗体显示,在表格中也可以不用此标签,<th>标签必须放在<tr>标签内\r\n\r\n<tr>...</tr> 定义一行标签,一组行标签内可以建立多组由<td>或<th>标签所定义的单元格\r\n\r\n<td>...</td> 定义单元格标签,一组<td>标签将将建立一个单元格,<td>标签必须放在<tr>标签内', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3040, 'page-inserts-the-picture-scroll-in-codes', '网页中插入图片滚动代码', '2011-12-10 03:28:04', '2019-03-25 21:29:22', '    代码:\r\n      <div id=\"demo\" style=\"overflow:hidden;width:670px;color:#ffffff;\">\r\n<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\r\n<tr><td id=\"demo1\" valign=\"top\" align=\"center\">\r\n<table cellpadding=\"2\" cellspacing=\"0\" border=\"0\">\r\n<tr align=\"center\">\r\n<td><img src=\"../upFiles/infoImg/2011112141076049.jpg\" ></td>\r\n<td><img src=\"../upFiles/infoImg/2011112141076049.jpg\" ></td>\r\n<td><img src=\"../upFiles/infoImg/2011112141076049.jpg\" ></td>\r\n<td><img src=\"../upFiles/infoImg/2011112141076049.jpg\" ></td>\r\n<td><img src=\"../upFiles/infoImg/2011112141076049.jpg\" ></td>\r\n</tr>\r\n</table>\r\n</td>\r\n<td id=\"demo2\" valign=\"top\"></td>\r\n</tr>\r\n</table>\r\n</div>\r\n<script>\r\nvar speed=8//速度数值越大速度越慢\r\ndemo2.innerHTML=demo1.innerHTML\r\nfunction Marquee(){\r\nif(demo.scrollLeft<=0)\r\ndemo.scrollLeft+=demo2.offsetWidth\r\nelse{\r\ndemo.scrollLeft--\r\n}\r\n}\r\nvar MyMar=setInterval(Marquee,speed)\r\ndemo.onmouseover=function() {clearInterval(MyMar)}\r\ndemo.onmouseout=function() {MyMar=setInterval(Marquee,speed)}\r\n</script>\r\n\r\n  效果:\r\n
\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
\"\"\"\"\"\"\"\"\"\"
\r\n
\r\n
\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3041, 'page-scrolling-marquee-effect-code-and-scrolling-marquee-effect-making-demonstration', '网页滚动字幕效果代码及滚动字幕效果制作实例演示', '2011-12-10 02:33:54', '2019-03-25 21:29:22', '
\r\n\r\n    滚动字幕会让很多人感到兴奋,特别是第一次使用滚动字幕时,会爱不释手。滚动字幕我也做得不少了,对它也不会兴奋了,所以现在也用得不多了。有不少朋友常问到这是怎么做的,现在做一个详细的专题,让你更全面地了解一下。\r\nDreamweaver只能用编写HTML代码的方法。所以强烈建议用记事本打开网页源代码来编辑。\r\n\r\n    1.建立第一个滚动字幕。\r\n代码:\r\n<marquee scrollAmount=2 width=300>新价值网-新技术!新价值!以技术为中心,百花齐放,百家争鸣!</marquee>\r\n效果如下:\r\n新价值网-新技术!新价值!以技术为中心,百花齐放,百家争鸣!\r\n    2.各参数详解:\r\na)scrollAmount。它表示速度,值越大速度越快。如果没有它,默认为6,建议设为1~3比较好。\r\nb)width和height,表示滚动区域的大小,width是宽度,height是高度。特别是在做垂直滚动的时候,一定要设height的值。\r\nc)direction。表示滚动的方向,默认为从右向左:←←←。可选的值有right、down、up。滚动方向分别为:right表示→→→,up表示↑,down表示↓。\r\nd)scrollDelay,这也是用来控制速度的,默认为90,值越大,速度越慢。通常scrollDelay是不需要设置的。\r\ne)behavior。用它来控制属性,默认为循环滚动,可选的值有alternate(交替滚动)、slide(幻灯片效果,指的是滚动一次,然后停止滚动)\r\n\r\n    3.实例:\r\na)如何给滚动字幕加超链接?这跟平时的超链接是完全一样的。只要加上<a href=\"URL\"></a>就可以了。如下效果,代码是:\r\n <marquee scrollAmount=2 width=300><a href=\"http://www.xinvalue.com\"target=\"_blank\">新价值网</a></marquee>\r\n新价值网\r\n
\r\n    b)如何制作当鼠标停留在文字上,文字停止滚动?\r\n代码:\r\n<marquee scrollAmount=2 width=300 onmouseover=stop() onmouseout=start()>文字内容</marquee>
\r\n
    效果:\r\n
\r\n \r\n
文字内容
\r\n c)交替效果。\r\n代码:\r\n<marquee scrollAmount=2 width=99 behavior=alternate>文字内容</marquee>\r\n 效果:\r\n\r\n  文字内容\r\n\r\n d)多行文本向上滚动。代码如:\r\n<marquee scrollAmount=2 width=300 height=160 direction=up>新价值网专注的领域有:<br>电脑技术,软件编程,源码分享,网站建设<br><p><a href=http://www.xinvalue.com /\">点这里进入了解新价值网</a></marquee>\r\n效果如下:\r\n\r\n新价值网专注的领域有:\r\n电脑技术,软件编程,源码分享,网站建设\r\n\r\n点这里进入了解新价值网\r\n\r\n \r\n\r\ne)改变滚动字幕的颜色?可以用样式表来控制。\r\n如下效果,代码是:\r\n<marquee scrollAmount=2 width=300><a style=color:CC6600>新技术!新价值!</a></marquee>\r\n\r\n新技术!新价值!\r\n

***原创文章,欢迎批评指正!***\r\n***@作者 桃源过客***\r\n***@QQ 1035136784***\r\n***@邮箱 cyutyw@126.com***

\r\n\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3042, 'jsp-to-connect-sql-server-2008-database', 'JSP连接Sql Server 2008数据库', '2011-12-08 08:36:01', '2019-08-25 16:57:36', '    1.打开Sql Server 2008数据库,创建一个数据库TEST,再创建一个表testTable,添加titlecontent两个项,再附上初值title=“数据库连接测试”,content=“欢迎来到Java Web世界!”。\r\n\"\"\r\n\r\n\"\"     2.然后打开MyEclipse,新建一个Web Project,项目名为SqlConnections,在Webroot下面创建一个cs08.jsp文件。\r\n3.将下列代码复制到cs08.jsp中。\r\n<%@ page contentType=\"text/html;charset=UTF-8\" import=\"java.sql.*\"%>\r\n<html>\r\n<head>\r\n<title>JSP连接SqlServer2008!</title>\r\n</head>\r\n<body>\r\n<%\r\nString driver=\"com.microsoft.sqlserver.jdbc.SQLServerDriver\";//驱动类\r\nConnection conn;\r\nString url=\"jdbc:sqlserver://localhost:1433;databaseName=TEST\";//连接数据库的地址\r\nString username=\"sa\";//数据库用户名\r\nString password=\"105036\";//数据库密码\r\nStatement stmt;\r\nString sql=\"select * from testTable;\";//查询语句\r\nResultSet rs;//结果集\r\ntry{\r\nClass.forName(driver);//加载驱动器\r\nconn=DriverManager.getConnection(url,username,password);//建立连接\r\nstmt=conn.createStatement();//建立处理的SQL语句\r\nrs=stmt.executeQuery(sql);//形成结果集\r\nwhile(rs.next()){//输出显示\r\nout.println(\"<center><tr><td>\"+rs.getString(\"title\")+\"</td></tr></center><br>\");\r\nout.println(\"<center><tr><td>\"+rs.getString(\"content\")+\"</td></tr></center> <br>\");\r\n}\r\nrs.close();//关闭结果集\r\nstmt.close();//关闭SQL语句集\r\nconn.close();//关闭连接\r\n}\r\n//捕获异常\r\ncatch(ClassNotFoundException e){\r\nSystem.out.print(e);\r\n}\r\n//捕获异常\r\ncatch(SQLException ee){\r\nSystem.out.print(ee);\r\n}\r\n%>\r\n</body>\r\n</html>\r\n\"\"\r\n4.打开MyEclipse中SqlConnections项目的文件夹,找到WebRoot->WEB-INFO->lib,将Sql Server 2008的驱动(驱动见附件)复制到lib文件夹下(非常重要)\r\n5.在MyEclipse中打开Tomcat6.0服务器,然后将SqlConnections这个项目部署到Tomcat中。\r\n\"\"\r\n6.打开IE浏览器,在地址栏输入http://localhost:8080/SqlConnections/cs08.jsp,按下enter键,如果成功,你将看到如下界面:\r\n\"\"\r\n

\r\n附件下载:Sql Server 2008的JDBC驱动

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3043, 'netbeans-performance-tuning-and-speed', 'Netbeans性能调优及加速', '2011-12-02 22:40:10', '2019-03-25 21:29:22', '    NetBeans安装目录下的netbeans.conf 文件中的netbeans_default_options 能够对NetBeans的启动,运行以及编译的速度产生很大的影响,恰当地设值可以让NetBeans的性能有大幅提升,当然如果设置的值过高也能导致NetBeans无法启动。\r\n\r\n    我的内存是2GB的,netbeans_default-options设置为以下的参数,运行速度很快,在这里做个备份供以后参考。\r\n\r\n    1.修改英文netbeans界面字体大小,修改%Netbeans_home%(Netbeans的安装目录)etcnetbeans.conf\r\n在netbeans_default_options里加上 –fontsize 13\r\n\r\n    2.修改JVM内存配置(本机内存1G,不同内存大小不同设置)\r\n在netbeans_default_options里加上 -J-Xmx512m,同时修改-J-Xms256m。\r\n\r\n【说明】-J-Xms32m\r\n\r\n    此设置用于通知 Java 虚拟机将其初始堆大小设置为 32 MB。通过通知 JVM 它最初应该为堆分配多少内存,我们可以防止它随着 IDE 使用更多的内存而将堆增大。\r\n\r\n【说明】-J-Xmx128m\r\n\r\n    此设置用于指定 Java 虚拟机应该用于堆的最大内存。对此数值设置硬性上限意味着 Java 进程不能使用比可用的物理 RAM 更多的内存。对于具有更多内存的系统可以提升此限制 – 128 MB 设置有助于确保 IDE 在 256MB 的系统上可靠地执行操作。注意:不要将此值设置为接近或大于系统中的物理 RAM 数,否则在主要回收过程中将导致频繁的交换空间操作。\r\n\r\n    3.在netbeans_default_options里修改 -J-XX:PermSize=20m\r\n\r\n    这是一个较特殊的 JVM 开关,但它也缩短了启动时间。此设置用于调整内存中“永久区域”(在这里保存类)的大小。由于我们知道所有 IDE 类均占用特定数量的内存,因此我们向 JVM 提示它将需要的内存数量。此设置消除了许多系统上启动过程中的主要垃圾回收事件。SunONE Studio 或包括更多模块的其他 IDE 的用户可能希望将此数值设置得更高些。\r\n\r\n    4.在netbeans_default_options里加上-J-Xverify:none\r\n\r\n    此开关用于关闭 Java 字节码验证,从而加快类加载,以及消除在启动过程中仅为验证目的而加载类的需要。此开关将显著缩短启动时间。\r\n\r\n    5.在Tools-Plugins-installed里面把不需要的模块去掉\r\n\r\n    我这里去掉了 Glashfish;JSF;CVS;Subversion等。速度就得到很大提高了。当然如果你的开发需要这些模块就不需要去掉了。\r\n\r\n    6.修改编辑器配置\r\n\r\n    把所有的Javadoc自动弹出窗口去掉,把所有自动完成延时设置为0,把所有自动完成大小写敏感去掉。\r\n\r\n    注:在netbeans6的JAVA代码编辑器设置里面默认没有设置代码自动完成的延时设置了。可以自己手动加入到配置文件C:Documents and Settings%USER_NAME%(netbeans工作文档位置).netbeans6.0beta2configEditorstextx-java下的 properties.xml,加入\r\n\r\n【说明】\r\npreperties.xml文件默认不存在,只有在你修改了编辑器配置以后才会出现这个文件。\r\n\r\n    根据经验,Xmx应设为物理内存的一半,初始堆大小Xms是Xmx的1/2,比如1G内存的机器,Xms256m, Xmx512m\r\n\r\n    Netbeans5.5.1默认的PermSize是160m,如果在开发中经常遇到 java.lang.OutOfMemoryError: PermGen space的异常,可以将此PermSize设大一些。\r\n\r\n    下面列出了一些其他的 JVM 开关,在一些系统(而不是所有系统)上,这些开关会或多或少地影响 NetBeans 性能。尽管使用它们会产生一定的影响,但仍值得一试。\r\n\r\n* -J-XX:CompileThreshold=100\r\n\r\n    此开关将会延长启动时间,原因是:与不使用此开关的情况相比,HotSpot JVM 会以更快的速度将更多的方法编译到本地代码中。其结果是提高了IDE 运行时的性能,这是因为更多的 UI 代码将被编译而不是被解释。此值表示在编译一个方法之前必须调用它的次数。\r\n\r\n* -J-XX:+UseConcMarkSweepGC -J-XX:+UseParNewGC\r\n\r\n    如果出现垃圾回收意外中断的问题,则请尝试使用这些开关。此开关导致 JVM 对主要垃圾回收事件(如果在多处理器工作站上运行,则也适用于次要回收事件)使用不同的算法,这些算法不会影响整个垃圾回收进程。如果使用了 PermSize 开关,则还应向 netbeans.conf 文件中添加行 -J-XX:+CMSClassUnloadingEnabled,以便启用类卸载(使用此回收器时,缺省情况下不启用类卸载)。注意:目前尚不确定此回收器是提高还是降低单处理器计算机的性能。\r\n\r\n* -J-XX:+UseParallelGC\r\n\r\n    某些测试表明,至少在内存配置相当好的单处理器系统中,使用此回收算法可以将次要垃圾回收的持续时间减少一半。请注意,这是一个矛盾的问题 – 事实上此回收器主要适用于具有千兆字节堆的多处理器系统。尚无可用数据表明它对主要垃圾回收的影响。注意:此回收器与 -J-XX:+UseConcMarkSweepGC 是互斥的。可以在性能 Web 站点上找到支持使用此算法的度量数据。\r\n\r\n* -J-XX:+UseConcMarkSweepGC-J-XX:+CMSClassUnloadingEnabled-J-XX:+CMSPermGenSweepingEnabled,是优化垃圾回收的。\r\n

***原创文章,欢迎批评指正!***\r\n***@作者 桃源过客***\r\n***@QQ 1035136784***\r\n***@邮箱 cyutyw@126.com***

\r\n ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3044, 'the-db2-jdbc-driver-installation-and-examples', 'db2的jdbc驱动安装及例子', '2011-11-29 17:13:42', '2019-03-25 21:29:22', '    1. db2数据库驱动的安装\r\n一种方法是安装db2客户端;\r\n还有一种是把db2的jdbc驱动放到jdk,jre或者tomcat的common/lib目录下,这样就在开发和运行环境下部署了db2的jdbc驱动。\r\n2.db2的数据库驱动有以下几种:\r\n第一种是COM.ibm.db2.jdbc.app.DB2Driver;\r\n另一种是COM.ibm.db2.jdbc.net.DB2Driver 这两种都在db2java.zip文件中,可以把他改名成db2java.jar文件使用。\r\n第三种是通用驱动程序,放在文件db2jcc.jar文件中。 这三种驱动的程序加载和连接建立方法如下:\r\nClass.forName(\"COM.ibm.db2.jdbc.app.DB2Driver\");\r\nClass.forName(\"COM.ibm.db2.jdbc.net.DB2Driver\");\r\nClass.forName(\"com.ibm.db2.jcc.DB2Driver\"); \r\n连接例子可以相同,都是指定主机,端口和数据库名称\r\nString dbUrl =\"jdbc:db2://localhost:6789/sample\";\r\ncon = DriverManager.getConnection(dbUrl,\"www\",\"123456\"); \r\n\r\n2.连接的例子: \r\n\r\n    <%@page import=\"java.sql.*\" pageEncoding=\"utf-8\"%>\r\n\r\n<%\r\nClass.forName(\"com.ibm.db2.jcc.DB2Driver\");\r\n\r\n//注册驱动程序\r\n//DriverManager.registerDriver(new COM.ibm.db2.jdbc.app.DB2Driver());\r\n\r\n//用适当的驱动程序连接到数据库\r\n//指定db2的url,注意格式,6789是端口,mytest是数据库名\r\nString dbUrl =\"jdbc:db2://localhost:50000/TEST\";\r\nConnection con = DriverManager.getConnection(dbUrl,\"db2admin\",\"105036\");\r\n\r\n//创建一个JDBC声明\r\nStatement stmt = con.createStatement();\r\n\r\n//增加新记录\r\n//stmt.executeUpdate(\"INSERT INTO books (id,name,title,price) VALUES (\'999\',\'Tom\',\'Tomcat Bible\',44.5)\");\r\n\r\n//查询记录\r\nResultSet rs = stmt.executeQuery(\"select * from TET\");\r\n\r\n//输出查询结果\r\nout.println(\"<table border=1 width=400>\");\r\nwhile (rs.next())\r\n{\r\nString col1 = rs.getString(1);\r\nString col2 = rs.getString(2);\r\n//打印所显示的数据\r\nout.println(\"<tr><td>\"+col1+\"</td><td>\"+col2+\"</td>\"+\"</tr>\");\r\n}\r\nout.println(\"</table>\");\r\n\r\n//关闭数据库连结\r\nrs.close();\r\nstmt.close();\r\ncon.close();\r\n%>\r\n

***原创文章,欢迎批评指正!***\r\n***@作者 桃源过客***\r\n***@QQ 1035136784***\r\n***@邮箱 cyutyw@126.com***

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3045, 'form-validation-encyclopedia-1-password-authentication', '表单验证大全1:密码验证', '2011-11-27 22:02:06', '2019-03-25 21:29:22', '代码:\r\n<form name=\"form\" action=\" \">\r\n\r\n<input type=\"password\" name=\"pwd1\" onblur=\"javascript:if(this.value.length<6){alert(\'密码设置少于6位,请重新输入!\');return false;}\" /><br>\r\n<input type=\"password\" name=\"pwd2\" onblur=\"javascript:if(this.value!=document.form.pwd1.value){alert(\'两次输入的密码错误!\');return false;}\" />\r\n\r\n</form>\r\n\r\n预览:\r\n\r\n
密    码:\r\n重复密码: \r\n

***原创文章,欢迎批评指正!***\r\n***@作者 桃源过客***\r\n***@QQ 1035136784***\r\n***@邮箱 cyutyw@126.com***

\r\n\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3046, 'document-location-href-differ-from-document-location-replace', 'document.location.href和document.location.replace区别', '2011-11-27 00:31:13', '2019-03-25 21:29:22', '
\r\n\r\n    document.location.href和document.location.replace都可以实现从A页面切换到B页面,但他们的区别是:\r\n用document.location.href切换后,可以退回到原页面。\r\n而用document.location.replace切换后,不可以通过“后退”退回到原页面。\r\n\r\n    关于document.location.href或其他可回退的切换方式,我还发现一个细节,\r\n用个例子来说明:\r\n假设有A.htm B.htm C.htm三个页面\r\nA.htm里有这样一句:document.location.href=\"b.htm\";\r\nb.htm里有这样一句:document.location.href=\"c.htm\";\r\n注意两个都是可回退的切换。\r\n1:当从A切换到B再切换到C时,实际内存中保留了三个页面:A、B、C\r\n2:回退到B时,C页面被清出内存!\r\n3:再次回退,到A页面时,B页面也被清出内存!\r\n4:再次向前(不是用切换而是用向前)转到B页面时,内存中保留的是A和B\r\n当一个文档被location.replace()替换后,它就会从当前的历史对象中移除了。\r\n\r\n
\r\n ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3047, 'in-the-text-box-the-search-box-method-of-adding-a-background-picture', '在文本框(搜索框)中加入背景图片的方法', '2011-11-26 19:41:03', '2019-03-25 21:29:22', '     不知细心的朋友有没有发现,在某些网站的输入框中有漂亮的背景图片,有些是用来提醒用户输入哪些内容,有些则是纯属装饰,下面就介绍一下在文本框(搜索框)中加入背景图片的方法。具体代码如下:\r\n\r\n<input type=\"text\" name=\"content\" size=\"20\" style=\"background-image:url(\'img.jpg\')\"> \r\n上面的代码中img.jpg即为图片的路径,换上你所需要的图片路径即可。\r\n

***原创文章,欢迎批评指正!***\r\n***@作者 桃源过客***\r\n***@QQ 1035136784***\r\n***@邮箱 cyutyw@126.com***

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3048, 'java-printwriter-methods-in-use', 'Java中的PrintWriter方法的使用', '2011-11-21 19:10:00', '2019-03-25 21:29:22', 'File f= new File(\"F:\\lxh.txt\") ;\r\nPrintWriter out = new PrintWriter(new FileWriter(f)) ;\r\nout.println(true) ;\r\n\r\nPrintWriter out = new PrintWriter(System.out) ;\r\nout.println(true) ;\r\n上面那段代码是打印在文件里,下面这段代码是打印在屏幕上。这两段代码各自是怎样实例化对象,然后调用方法的,调用的是哪个类的方法,解释如下:\r\nFile f = new File(\"F:\\lxh.txt\") ;\r\n//f对象建立f:\\lxh.txt的文件关联。\r\nPrintWriter out = new PrintWriter(new FileWriter(f)) ;\r\n//out对象对[f抽象文件的文件输出流]做打印输出流工作\r\nout.println(true) ;\r\n//向输出流里写数据\r\n\r\nPrintWriter out = new PrintWriter(System.out) ;\r\nout输出流关联到标准输出对象(屏幕)\r\n

***原创文章,欢迎批评指正!***\r\n***@作者 桃源过客***\r\n***@QQ 1035136784***\r\n***@邮箱 cyutyw@126.com***

\r\n ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3049, 'jdbc-database-details', 'JDBC数据库详解', '2011-11-19 02:51:03', '2019-03-25 21:29:22', '
一、SQL语言回顾\r\n注:T为表名,t1,t2,t3为表中的元素
\r\n
1、Select select * from T where …
\r\n
2、Insert insert into T values(…)
\r\n
3、Create create table T(…)
\r\n
4、Delete delete from T where…
\r\n
5、Update update T set t1=… and t2=.. where t3=…
\r\n
6、Drop drop table T
\r\n
 
\r\n
二、JDBC编程步骤
\r\n
1、加载驱动程序(Load the Driver)
\r\n
Class.forName(驱动);
\r\n
2、 连接到数据库(Connect to the DataBase)
\r\n
DriverManager.getConnection( );
\r\n
3、执行SQL(Execute the SQL)
\r\n
Connection.CreateStatement( );
\r\n
Statement.executeQuery( );
\r\n
Statement.executeUpdate( );
\r\n
4、检索结果数据(Retrieve the result data)
\r\n
while(rs.next( ))\r\n{\r\n}
\r\n
5、显示结果数据(Show the result data);
\r\n
将数据库中的各种类型转换为Java中的类型(getXXX)方法
\r\n
6、关闭数据库查询(Close database query)
\r\n
Close the resultset\r\nclose the statement\r\nclose the connection
\r\n
 
\r\n
三、JDBC操作oracle数据库
\r\n
1、 JDBC连接oracle数据库:
\r\n
import java.sql.*;
\r\n
public class TestJDBC {
\r\n
public static void main(String[] args) throws ClassNotFoundException, SQLException {
\r\n
Class.forName(\"oracle.jdbc.driver.OracleDriver\");
\r\n
//new oracle.jdbc.driver.OracleDriver();
\r\n
Connection conn = DriverManager.getConnection(\"jdbc:oracle:thin:@127.0.0.1:1521:solid\", \"scott\", \"tiger\");
\r\n
}
\r\n
}
\r\n
 
\r\n
2、 向数据库中取字段,遍历数据库,并显示出相应字段:
\r\n
import java.sql.*;
\r\n
public class TestJDBC {
\r\n
public static void main(String[] args) throws ClassNotFoundException, SQLException {
\r\n
Class.forName(\"oracle.jdbc.driver.OracleDriver\");
\r\n
//new oracle.jdbc.driver.OracleDriver();
\r\n
Connection conn = DriverManager.getConnection(\"jdbc:oracle:thin:@127.0.0.1:1521:solid\", \"scott\", \"tiger\");
\r\n
Statement stmt = conn.createStatement();
\r\n
ResultSet rs = stmt.executeQuery(\"select * from dept\");
\r\n
while(rs.next()) {
\r\n
System.out.println(rs.getString(\"deptno\"));
\r\n
System.out.println(rs.getInt(\"deptno\"));
\r\n
}
\r\n
rs.close();
\r\n
stmt.close();
\r\n
conn.close();
\r\n
}
\r\n
}
\r\n
 
\r\n
3、 捕捉相关异常,完善JDBC编程:
\r\n
import java.sql.*;
\r\n
public class TestJDBC {
\r\n
public static void main(String[] args) throws ClassNotFoundException, SQLException {
\r\n
ResultSet rs = null;
\r\n
Statement stmt = null;
\r\n
Connection conn = null;
\r\n
try {
\r\n
Class.forName(\"oracle.jdbc.driver.OracleDriver\");
\r\n
conn = DriverManager.getConnection(\"jdbc:oracle:thin:@127.0.0.1:1521:solid\", \"scott\", \"tiger\");
\r\n
stmt = conn.createStatement();
\r\n
rs = stmt.executeQuery(\"select * from dept\");
\r\n
while(rs.next()) {
\r\n
System.out.println(rs.getString(\"deptno\"));
\r\n
System.out.println(rs.getInt(\"deptno\"));
\r\n
}
\r\n
} catch(ClassNotFoundException e) {
\r\n
e.printStackTrace();
\r\n
} catch(SQLException e) {
\r\n
e.printStackTrace();
\r\n
} finally {
\r\n
try {
\r\n
if(rs != null) {
\r\n
rs.close();
\r\n
rs = null;
\r\n
}
\r\n
if(stmt != null) {
\r\n
stmt.close();
\r\n
stmt = null;
\r\n
}
\r\n
if(conn != null) {
\r\n
conn.close();
\r\n
conn = null;
\r\n
}
\r\n
} catch(SQLException e) {
\r\n
e.printStackTrace();
\r\n
}
\r\n
}
\r\n
}
\r\n
}
\r\n
 
\r\n
四、JDBC编程高级
\r\n
1、 JDBC处理DML语句:
\r\n
import java.sql.*;
\r\n
public class TestDML {
\r\n
public static void main(String[] args) {
\r\n
Connection conn = null;
\r\n
Statement stmt = null;
\r\n
try {
\r\n
Class.forName(\"oracle.jdbc.driver.OracleDriver\");
\r\n
conn = DriverManager.getConnection(
\r\n
\"jdbc:oracle:thin:@127.0.0.1:1521:solid\", \"scott\", \"tiger\");
\r\n
stmt = conn.createStatement();
\r\n
String sql = \"insert into dept2 values (99,\'develop\',\'changsha\')\";
\r\n
stmt.executeUpdate(sql);
\r\n
} catch (ClassNotFoundException e) {
\r\n
e.printStackTrace();
\r\n
} catch (SQLException e) {
\r\n
e.printStackTrace();
\r\n
} finally {
\r\n
try {
\r\n
if (stmt != null) {
\r\n
stmt.close();
\r\n
stmt = null;
\r\n
}
\r\n
if (conn != null) {
\r\n
conn.close();
\r\n
conn = null;
\r\n
}
\r\n
} catch (SQLException e) {
\r\n
e.printStackTrace();
\r\n
}
\r\n
}
\r\n
}
\r\n
}
\r\n
 
\r\n
2、 JDBC处理DML语句2:
\r\n
import java.sql.*;
\r\n
public class TestDML2 {
\r\n
public static void main(String[] args) {
\r\n
if (args.length != 3) {
\r\n
System.out.println(\"Arguments error,please enter again!\");
\r\n
System.exit(-1);
\r\n
}
\r\n
 
\r\n
int deptno = 0;
\r\n
try {
\r\n
deptno = Integer.parseInt(args[0]);
\r\n
} catch (NumberFormatException e) {
\r\n
System.out.println(\"Arguments error\");
\r\n
System.exit(-1);
\r\n
}
\r\n
 
\r\n
String dname = args[1];
\r\n
String loc = args[2];
\r\n
 
\r\n
Connection conn = null;
\r\n
Statement stmt = null;
\r\n
try {
\r\n
Class.forName(\"oracle.jdbc.driver.OracleDriver\");
\r\n
conn = DriverManager.getConnection(\"jdbc:oracle:thin:@127.0.0.1:1521:solid\", \"scott\", \"tiger\");
\r\n
stmt = conn.createStatement();
\r\n
String sql = \"insert into dept2 values (\" + deptno + \",\'\" + dname + \"\',\'\" + loc + \"\' )\";
\r\n
System.out.println(sql);
\r\n
stmt.executeUpdate(sql);
\r\n
} catch (ClassNotFoundException e) {
\r\n
e.printStackTrace();
\r\n
} catch (SQLException e) {
\r\n
e.printStackTrace();
\r\n
} finally {
\r\n
try {
\r\n
if (conn != null) {
\r\n
conn.close();
\r\n
conn = null;
\r\n
}
\r\n
if (stmt != null) {
\r\n
stmt.close();
\r\n
stmt = null;
\r\n
}
\r\n
} catch (SQLException e) {
\r\n
e.printStackTrace();
\r\n
}
\r\n
}
\r\n
}
\r\n
}
\r\n
 
\r\n
3、 JDBC处理PreparedStatement,可以灵活指定SQL语句中的变量
\r\n
import java.sql.*;
\r\n
public class TestPrepStmt {
\r\n
public static void main(String[] args) {
\r\n
if (args.length != 3) {
\r\n
System.out.println(\"Arguments error,please enter again!\");
\r\n
System.exit(-1);
\r\n
}
\r\n
int deptno = 0;
\r\n
try {
\r\n
deptno = Integer.parseInt(args[0]);
\r\n
} catch (NumberFormatException e) {
\r\n
System.out.println(\"Arguments error\");
\r\n
System.exit(-1);
\r\n
}
\r\n
 
\r\n
String dname = args[1];
\r\n
String loc = args[2];
\r\n
 
\r\n
Connection conn = null;
\r\n
PreparedStatement pstmt = null;
\r\n
try {
\r\n
Class.forName(\"oracle.jdbc.driver.OracleDriver\");
\r\n
conn = DriverManager.getConnection(\"jdbc:oracle:thin:@127.0.0.1:1521:solid\", \"scott\", \"tiger\");
\r\n
pstmt = conn.prepareStatement(\"insert into dept2 values (?, ?, ?)\");
\r\n
pstmt.setInt(1, deptno);
\r\n
pstmt.setString(2, dname);
\r\n
pstmt.setString(3, loc);
\r\n
pstmt.executeUpdate();
\r\n
} catch (ClassNotFoundException e) {
\r\n
e.printStackTrace();
\r\n
} catch (SQLException e) {
\r\n
e.printStackTrace();
\r\n
} finally {
\r\n
try {
\r\n
if (conn != null) {
\r\n
conn.close();
\r\n
conn = null;
\r\n
}
\r\n
if (pstmt != null) {
\r\n
pstmt.close();
\r\n
pstmt = null;
\r\n
}
\r\n
} catch (SQLException e) {
\r\n
e.printStackTrace();
\r\n
}
\r\n
}
\r\n
}
\r\n
}
\r\n
 
\r\n
4、 JDBC处理储存过程
\r\n
import java.sql.*;
\r\n
public class TestProc {
\r\n
public static void main(String[] args) throws Exception {
\r\n
Class.forName(\"oracle.jdbc.driver.OracleDriver\");
\r\n
Connection conn = DriverManager.getConnection(\"jdbc:oracle:thin:@192.168.0.1:1521:SXT\", \"scott\", \"tiger\");
\r\n
CallableStatement cstmt = conn.prepareCall(\"{call p(?, ?, ?, ?)}\");
\r\n
cstmt.registerOutParameter(3, Types.INTEGER);
\r\n
cstmt.registerOutParameter(4, Types.INTEGER);
\r\n
cstmt.setInt(1, 3);
\r\n
cstmt.setInt(2, 4);
\r\n
cstmt.setInt(4, 5);
\r\n
cstmt.execute();
\r\n
System.out.println(cstmt.getInt(3));
\r\n
System.out.println(cstmt.getInt(4));
\r\n
cstmt.close();
\r\n
conn.close();
\r\n
}
\r\n
 
\r\n
}
\r\n
 
\r\n
5、 JDBC进行批处理
\r\n
import java.sql.*;
\r\n
public class TestBatch {
\r\n
public static void main(String[] args) throws Exception {
\r\n
Class.forName(\"oracle.jdbc.driver.OracleDriver\");
\r\n
Connection conn = DriverManager.getConnection(\"jdbc:oracle:thin:@192.168.0.1:1521:SXT\", \"scott\", \"tiger\");
\r\n
/*
\r\n
Statement stmt = conn.createStatement();
\r\n
stmt.addBatch(\"insert into dept2 values (51, \'500\', \'haha\')\");
\r\n
stmt.addBatch(\"insert into dept2 values (52, \'500\', \'haha\')\");
\r\n
stmt.addBatch(\"insert into dept2 values (53, \'500\', \'haha\')\");
\r\n
stmt.executeBatch();
\r\n
stmt.close();
\r\n
*/
\r\n
 
\r\n
PreparedStatement ps = conn.prepareStatement(\"insert into dept2 values (?, ?, ?)\");
\r\n
ps.setInt(1, 61);
\r\n
ps.setString(2, \"haha\");
\r\n
ps.setString(3, \"bj\");
\r\n
ps.addBatch();
\r\n
 
\r\n
ps.setInt(1, 62);
\r\n
ps.setString(2, \"haha\");
\r\n
ps.setString(3, \"bj\");
\r\n
ps.addBatch();
\r\n
 
\r\n
ps.setInt(1, 63);
\r\n
ps.setString(2, \"haha\");
\r\n
ps.setString(3, \"bj\");
\r\n
ps.addBatch();
\r\n
 
\r\n
ps.executeBatch();
\r\n
ps.close();
\r\n
 
\r\n
conn.close();
\r\n
 
\r\n
}
\r\n
 
\r\n
}
\r\n
 
\r\n
6、 JDBC处理Transaction
\r\n
import java.sql.*;
\r\n
public class TestTransaction {
\r\n
public static void main(String[] args) {
\r\n
Connection conn = null;
\r\n
Statement stmt = null;
\r\n
try {
\r\n
Class.forName(\"oracle.jdbc.driver.OracleDriver\");
\r\n
conn = DriverManager.getConnection(\"jdbc:oracle:thin:@127.0.0.1:1521:SXT\", \"scott\", \"tiger\");
\r\n
 
\r\n
conn.setAutoCommit(false);
\r\n
stmt = conn.createStatement();
\r\n
stmt.addBatch(\"insert into dept2 values (51, \'500\', \'haha\')\");
\r\n
stmt.addBatch(\"insert into dept2 values (52, \'500\', \'haha\')\");
\r\n
stmt.addBatch(\"insert into dept2 values (53, \'500\', \'haha\')\");
\r\n
stmt.executeBatch();
\r\n
conn.commit();
\r\n
conn.setAutoCommit(true);
\r\n
} catch (ClassNotFoundException e) {
\r\n
e.printStackTrace();
\r\n
} catch(SQLException e) {
\r\n
 
\r\n
e.printStackTrace();
\r\n
 
\r\n
try {
\r\n
if(conn != null)
\r\n
{
\r\n
conn.rollback();
\r\n
conn.setAutoCommit(true);
\r\n
}
\r\n
} catch (SQLException e1) {
\r\n
e1.printStackTrace();
\r\n
}
\r\n
}finally {
\r\n
try {
\r\n
if(stmt != null)
\r\n
stmt.close();
\r\n
if(conn != null)
\r\n
conn.close();
\r\n
} catch (SQLException e) {
\r\n
e.printStackTrace();
\r\n
}
\r\n
}
\r\n
}
\r\n
}
\r\n
 
\r\n
7、 JDBC处理可滚动的结果
\r\n
import java.sql.*;
\r\n
public class TestScroll {
\r\n
public static void main(String args[]) {
\r\n
 
\r\n
try {
\r\n
new oracle.jdbc.driver.OracleDriver();
\r\n
String url = \"jdbc:oracle:thin:@192.168.0.1:1521:SXT\";
\r\n
Connection conn = DriverManager
\r\n
.getConnection(url, \"scott\", \"tiger\");
\r\n
Statement stmt = conn.createStatement(
\r\n
ResultSet.TYPE_SCROLL_INSENSITIVE,
\r\n
ResultSet.CONCUR_READ_ONLY);
\r\n
ResultSet rs = stmt
\r\n
.executeQuery(\"select * from emp order by sal\");
\r\n
rs.next();
\r\n
System.out.println(rs.getInt(1));
\r\n
rs.last();
\r\n
System.out.println(rs.getString(1));
\r\n
System.out.println(rs.isLast());
\r\n
System.out.println(rs.isAfterLast());
\r\n
System.out.println(rs.getRow());
\r\n
rs.previous();
\r\n
System.out.println(rs.getString(1));
\r\n
rs.absolute(6);
\r\n
System.out.println(rs.getString(1));
\r\n
rs.close();
\r\n
stmt.close();
\r\n
conn.close();
\r\n
} catch (SQLException e) {
\r\n
e.printStackTrace();
\r\n
}
\r\n
}
\r\n
}
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3050, 'how-to-restart-the-sql-server-2005-services', '如何重启SQL Server 2005 服务?', '2011-11-18 02:44:25', '2019-03-25 21:29:22', '打开‘开始’-‘所有程序’-‘Microsoft SQL Server 2005 ’-‘配置工具’-‘SQL Server 配置管理器’(SQL Server Configuration Manager),选择“SQL Server 2005 服务”,可以在右边右击选择需要重启的服务,进行“停止”、“暂停”、“重新启动”等动作。\r\n\"\"\r\n

***原创文章,欢迎批评指正!***\r\n***@作者 桃源过客***\r\n***@QQ 1035136784***\r\n***@邮箱 cyutyw@126.com***

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3051, 'in-sqlserver2005-and-how-do-i-create-a-username-and-password-for-the-sa-login', '在SqlServer2005中,怎样创建一个帐号和密码为sa的登录名。', '2011-11-18 02:13:22', '2019-03-25 21:29:22', '\"\"\r\n解决方法:\r\n先用windows身份验证方式登录,之后新建一个查询,执行以下命名:\r\n\r\nexec sp_password null, \'#karley\',\'sa\'\r\n\r\nalter login sa enable\r\n\r\n之后重启SQL服务(关于重启请参考http://www.xinvalue.com/news/?181.html)。\r\n\r\n然后登录即可!\r\n\r\n第一条格式:exec sp_password \'原密码\' \'新密码\' \'帐户名\'\r\n\r\n\"\"\r\n
\r\n
\r\n
\r\n
\r\n\"\"\r\n\r\n\"\"
\r\n
\r\n
\r\n
\r\n ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3052, 'android-tutorial-2-to-form-a-development-environment-eclipsewin7-new', 'Android学习笔记001:1.2搭建开发环境(Eclipse+win7最新)', '2011-11-16 01:59:55', '2019-03-25 21:29:22', '一.开发工具\r\n\r\n1.安装eclipse。其实很简单,下载解压即可。\r\n\r\n2.安装ADT插件,插件地址:https://dl-ssl.google.com/android/eclipse/。eclipse和ADT不是必须的,但他们能极大地简化android开发。\r\n\r\n 二.sdk下载安装\r\n\r\n1.从http://developer.android.com/sdk/index.html处下载sdk的壳。没错是壳。\r\n\r\n2.通过壳更新sdk。可以执行sdk/SDK Manager.exe来更新,也可以通过eclipse menu - Window - Android SDK and AVD Manager来更新。\r\n\r\n 三.创建模拟器\r\n\r\n1.eclipse menu - Window - Android SDK and AVD Manager - Virtual Devices - New按钮。如果看不到New按钮,请把窗体拉宽-_-!。\r\n\r\n2.填name,如\"adv2.2\"。\r\n\r\n3.选择Target,如Android 2.2。\r\n\r\n4.点Create AVD。\r\n\r\n现在你有一个2.2版本的android手机了。\r\n\r\n 四.开发\r\n\r\n1.eclipse menu - New - Android Project。\r\n\r\n2.填Project name,如\"at\"。\r\n\r\n3.选择Build Target,可以选最新的android版本,比如Android 2.2。但我一位牛人同事建议选择Android 1.6,同时下面的Min SDK Version填5。\r\n\r\n4.填Application name,如\"at_app_name\"。\r\n\r\n5.填Package name,如\"at_package_name\"。\r\n\r\n6.填Create Activity,如\"at_activity_name\"。\r\n\r\n7.Min SDK Version这里,如果第3步你没听我牛人同事的建议,那空着就行了。\r\n\r\n8.点ok,工程就建好了。\r\n\r\n9.你不需要写任何代码,默认会生成一个hello world。\r\n\r\n上面几个空填了不同的名字,是为了在例子中方便查看他们分别用在哪里。\r\n\r\n \r\n\r\n五.运行\r\n\r\n1.点eclipse的run。\r\n\r\n2.如果提示,选一个模拟器或真机。\r\n\r\n3.编译、打包、启动模拟器、安装、运行,一切都是自动的,稍等一会,你就可以看到\"Hello World, HelloWorldActivity!\"了。\r\n\"\"\r\n    如果有问题可以给我留言http://www.xinvalue.com/message.asp或QQ1035136784。\r\n

***原创文章,欢迎批评指正!***\r\n***@作者 桃源过客***\r\n***@QQ 1035136784***\r\n***@邮箱 cyutyw@126.com***

\r\n ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3054, 'a-simple-applet', 'Java学习笔记001-【1.2】一个简单的Applet程序', '2011-11-14 19:21:36', '2019-03-25 21:29:22', '1.首先在记事本中写入如下代码,保存为NewClass.java\r\n\r\nimport java.awt.*;\r\n\r\nimport java.applet.*;\r\n\r\npublic class NewClass extends Applet\r\n\r\n{\r\n\r\npublic void paint(Graphics g)\r\n\r\n{\r\n\r\ng.drawString(\"HelloWorld\",30,30);\r\n\r\n}\r\n}\r\n\r\n2.在html中写如下面的内容,保存为NewClass.html\r\n\r\n <applet code=HelloWorld with=200 height=200>\r\n</applet>\r\n\r\n3.打开运行,进入cmd,再用CD命令进入文件所在目录。\r\n\r\n4.输入javac NewClass.java编译,会看到同一目录生成NewClass.class文件。\r\n\r\n5.输入appletviewer NewClass.html命令。\r\n\r\n你也可以直接点击NewClass.html图标,用浏览器运行。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3055, 'jsp-garbled-solution', 'JSP中文乱码问题解决办法', '2011-11-14 03:52:01', '2019-03-25 21:29:22', '    当用request对象获取客户提交的汉字字符时,会出现乱码问题,所以对含有汉字字符的信息必须进行特殊处理。\r\n    常见的几种字符集编码:\r\nn  ASCII码:不支持中文\r\nn  ISO-8859-1:不支持中文\r\nn  GB2313GBK:支持中文\r\nn  Unicode:支持中文\r\nn  UTF-8支持中文\r\n    在解决JSP中文乱码问题前,弄清以下几点:\r\n(1) windows平台采用的默认字符集编码是:GBK\r\n(2) IE浏览器默认采用UTF-8字符集编码方式发送Http请求。\r\n(3) Tomcat在处理Get请求时,永远采用ISO-8859-1编码;\r\nTomcat在处理Post请求时,默认采用ISO-8859-1编码;如果进行了如下设置request.setCharacterEncoding(“GBK”),则采用GBK编码。\r\n\r\n可以使用如下几种方式解决JSP中文乱码问题。\r\n

     1、方法一:调用自定义的转换函数

\r\n

<%@ page contentType=\"text/html;charset=GB2312\" %>

\r\n

<%!

\r\n

public String getStr(String s) {

\r\n

       

\r\n

String str = s;

\r\n

       

\r\n

try {

\r\n

           

\r\n

byte[] b = str.getBytes(\"ISO-8859-1\");

\r\n

           

\r\n

str = new String(b);

\r\n

           

\r\n

return str;

\r\n

           

\r\n

} catch (Exception e) {

\r\n

           

\r\n

return str;

\r\n

}

\r\n

}

\r\n

%>   

\r\n

\r\n

    使用内置对象request将获取的数据,使用ISO-8859-1进行重新编码,并保存到一个字节数组中,然后调用new String()方法,以GBK方式将这个字节数组构造出一个新的字符串,这个新的字符串就是我们想要的结果。

\r\n

\r\n

适用于以下三种情况:

\r\n

(1) Get方式提交表单,提交的数据中包含汉字字符。

\r\n

(2) Post方式提交表单,提交的数据中包含汉字字符。

\r\n

(3) 在浏览器的地址栏中发出Http请求时,查询字符串中包含汉字字符。

\r\n

     2、方法二:调用request.setCharacterEncoding(“GBK”);

\r\n

<%@ page contentType=\"text/html;Charset=GB2312\" pageEncoding=\"GBK\" %>

\r\n

<% request.setCharacterEncoding(\"GB2312\"); %>

\r\n

\r\n

由于Tomcat服务器处理Get请求或Post请求时,默认采用的编码方式是ISO-8859-1,通过内置对象requestgetParameter()方法得到的字符串是以ISO-8859-1转换而来,这是导致乱码产生的原因之一。\r\n为了避免TomcatISO-8859-1的编码方式返回字符串,对于以Post方式提交的表单数据,可以在通过内置对象request获取数据之前,调用request.setCharacterEncoding(“GBK”)明确指定对浏览器发送来的数据进行重新编码(或者称为解码)时,采用的GBK的编码方式。

\r\n

\r\n

适用于以下情况:

\r\n

Post方式提交表单,提交的数据中包含汉字字符。\r\n3、在数据库中存储和读取中文数据

\r\n

Java编程中,中文字体编码难倒了不少程序员,如果抓住了影响Java中文显示的几个关键因素,问题将迎刃而解。

\r\n

Java是目前最流行的面向对象的编程语言之一,Java支持UTF-8ISO-8859-1GBK等各种字体编码,可笔者发现Java中字体编码的问题仍难倒了不少程序员,网上虽然也有不少关于在Java中如何正确显示中文的文章,但都不够全面,笔者特意总结如下。

\r\n

影响Java中字体编码正确显示的有几个因素: 1)数据库的连接方式; 2)网页中使用的字体编码; 3)数据库里存放数据的字体编码; 4)Java的缺省字体编码。如果在编程中遇到不能正确显示中文时,要先弄清楚以上几项所使用的字体编码,再分析找出原因,即可解决问题。

\r\n

众所周知,JSPJava的一种,和网页有关,而网页也有自己的中文编码系统,所以JSP处理中文要比纯Java的类文件更为麻烦。本文的测试数据库是MySQL3.2,数据库连接驱动是用org.gjt.mm.mysql.Driver,这里主要讨论UTF-8GBK的显示( GB2312GBK的一个子集,Java中可以使用GBK来代替GB系列)。我们先来研究JSP中字体编码问题,下面第一到第六点是针对JSP(因为从数据库里读出中文数据与写入中文数据有所区别,咱们分别说明,前三点是从读取数据库到显示在网页,后三点是从网页输入数据到存入数据库),第七到第九点针对纯Java的类文件。以下rs表示ResultSet的一个实例,是执行Select语句之后产生的数据集。

\r\n

一、数据库连接方式使用UTF-8

\r\n

在连接数据库的驱动后面加上这句参数useUnicode=true&characterEncoding= UTF-8,例如jdbc:mysql://localhost/DBVF?autoReconnect=true&useUnicode= true&characterEncoding=UTF-8,从数据库里读出中文显示在使用GBKJSP的网页里,如果数据库里存放的字体编码是UTF-8,在JSP中使用 str=new String(rs.getBytes(1),\"UTF-8\")或者str=rs.getString(1),可以正确显示中文。如果数据库里存放的是GBK数据,那么JSP中也要使用str=new String(rs.getBytes(1),\"GBK\")来显示正确的中文。值得注意的是如果页面使用UTF-8,数据库里存放的是UTF-8,也可以用str=new String(rs.getBytes(1),\"GBK\")正确显示中文。如果网页是UTF-8,而数据库里存放的是GBK,无法直接显示中文,需要2步转换, str=new String(rs.getBytes(1),\"GBK\"); str=new String(str.getBytes(\"UTF-8\"),\"GBK\"),才可以正确显示中文。

\r\n

二、数据库连接方式使用GBK

\r\n

在连接数据库的驱动后面加上这句参数useUnicode=true&characterEncoding=

\r\n

GBK,例如jdbc:mysql://localhost/DBVF?autoReconnect=true&UseUnicode=true&

\r\n

characterEncoding=GBK,从数据库里读出中文,显示在使用GBKJSP的网页里,如果数据库里存放的字体编码是UTF-8,在JSP中一定要使用 str=new String(rs.getBytes(1),\"UTF-8\"),才正确显示中文。如果数据库里存放的是GBK数据,那么JSP中也要使用str=new String(rs.getBytes(1),\"GBK\") 或者直接使用str=rs.getString(1),即可显示正确的中文。如果网页是UTF-8,而数据库里存放的是GBK,只能用str=new String(rs.getString(1).getBytes(\"UTF-8\"),\"GBK\")的方法来显示中文; 如果网页是UTF-8,而数据库里存放的是UTF-8,可用str=new String(rs.getBytes(1),\"GBK\") 或者rs.getString(1)方法来显示中文。

\r\n

三、使用缺省数据库连接方式

\r\n

连接数据库的驱动后面没有这句参数useUnicode=&characterEncoding=,例如jdbc:mysql://localhost/DBVF?autoReconnect=true,没有参数useUnicode=true&characterEncoding,表示使用默认的ISO-8895-1编码。

\r\n

1. 从数据库里读出中文,显示在GBK的网页里。如果数据库里存放的字体编码是UTF-8,在JSP网页中一定要使用语句 str=new String(rs.getBytes(1),\"UTF-8\") 或者str= new String(rs.getString(1).getBytes(\"ISO-8859-1\"),\"UTF-8\"),才可正确显示中文。如果数据库里存放的是GBK数据,那么JSP中也要使用str=new String(rs.getBytes(1),\"GBK\")str=new String(rs.getString(1).getBytes(\"ISO-8859-1\"),\"GBK\") 显示正确的中文。

\r\n

2. 如果网页是UTF-8,不能直接正确显示GBK,需要2步转换,str=new String(rs.getBytes(1),\"GBK\"),再str=new String(str.getBytes(\"UTF-8\"),\"GBK\") 才可以正确显示中文。如果数据库里存的是UTF-8,直接用str=new String(rs.getBytes(1),\"GBK\")或者str=new String(rs.getString(1).getBytes(\"ISO-8859-1\"),\"GBK\")就可以显示中文了。

\r\n

以上是读取数据库里中文正确显示在网页上,下面三点是如何正确存入数据库。

\r\n

四、数据库连接方式使用UTF-8编码

\r\n

JSP中要把网页输入的中文存入数据库,通常有一个提交(Submit)的过程,是用str=request.getParameter(\"username\"),然后执行update或者insert语句来存入数据库。如何赋值给str很重要,而且这里中文输入与网页所使用的字体编码有关。

\r\n

1网页使用UTF-8,使用str= new String(request.getParameter(\"username\").getBytes(\"ISO-8859-1\"),\"UTF-8\")或者str= new String(request.getParameter(\"username\").getBytes(),\"UTF-8\"),都可以使得存到数据库里的数据是UTF-8编码。

\r\n

2. 网页使用GBK,使用str= new String(request.getParameter(\"username\").getBytes(),\"GBK\"),那么存入数据库的是UTF-8编码。

\r\n

3. 值得注意的是使用UTF-8的数据库连接方式不能存得GBK

\r\n

五、数据库连接方式使用GBK编码

\r\n

1. 输入使用GBK网页,存到数据库里是GBK的方法: str= new String(request.getParameter(\"username\").getBytes(\"ISO-8859-1\"),\"GBK\") 或者str= new String(request.getParameter(\"username\").getBytes(),\"GBK\")

\r\n

2. 网页使用GBK,想存入UTF-8到数据库里,要分2: str=new String(request.getParameter(\"username\").getBytes(),\"GBK\"),再str=new String(str.getBytes(\"UTF-8\"),\"GBK\")即可。

\r\n

3. 网页使用UTF-8,而且使用str= new String(request.getParameter(\"username\").getBytes(\"ISO-8859-1\"),\"GBK\") 或者str= new String(request.getParameter(\"username\").getBytes(),\"UTF-8\"),那么存到数据库里的数据是UTF-8编码。

\r\n

4. 网页使用UTF-8,而且使用str= new String(request.getParameter(\"username\").getBytes(\"ISO-8859-1\"),\"UTF-8\"),那么存到数据库里的数据是GBK编码。

\r\n

六、数据库连接方式使用缺省,即不使用参数useUnicodecharacterEncoding

\r\n

1. 网页使用GBK,如果使用str= request.getParameter(\"username\")或者str= new String(request.getParameter(\"username\").getBytes()),那么在数据库里的数据是GBK码。网页使用UTF-8 和使用str= request.getParameter(\"username\"),则存入数据库是UTF-8编码。

\r\n

2. 如果使用str= new String(request.getParameter(\"username\").getBytes(\"ISO-8859-1\")),那么根据网页提供的字体编码而存到数据库里,比如是UTF-8的网页,那么存到数据库中就是UTF-8编码,如果使用GBK网页,那么存到数据库里的字就是GBK编码。

\r\n

3. 如果使用str= new String(request.getParameter(\"username\").getBytes(\"UTF-8\"),\"UTF-8\")这一种组合能存到正确的数据外,其他存到数据库里的数据则都是乱码或者错误码。在这个UTF-8组合的特例中,网页使用的是GBK,则存放到数据库里就是GBK,网页使用UTF-8,那么存到数据库里的就是UTF-8

\r\n

4. 网页是GBK的要存得UTF-8,一定需要2: company=new String(request.getParameter(\"company\").getBytes(),\"GBK\")company=new String(company.getBytes(\"UTF-8\"))

\r\n

5. 网页是UTF-8的,不能存得GBK在数据库里,一句话,改变数据库连接方式不能存得GBK码。

\r\n

以上所有的都是基于JSP网页和数据库交换数据,下面讨论一下纯JAVA编程下的字体编码转换。

\r\n

七、数据库连接方式使用UTF-8编码

\r\n

1. 数据库里的中文是UTF-8,可以转换为GBK,但不能把GBK存入数据库。

\r\n

2. 数据库是GBK,如果转换为UTF-8,使用content=new String(rs.getBytes(2),\"GBK\")直接将content存入数据库就可为UTF-8

\r\n

八、数据库连接方式使用GBK编码

\r\n

1. 数据库里的中文是UTF-8,如果转换为GBK,使用content= new String(rs.getString(2).getBytes(),\"UTF-8\"),再直接使用update或者insert语句插入到数据库,即存得GBK。如果使用content= new String(rs.getString(2).getBytes(),\"GBK\")或者content= new String(rs.getString(2).getBytes()),再存入数据库即存得还是UTF-8编码。

\r\n

2. 数据库里的中文是GBK,如果转换为UTF-8,使用content= new String(rs.getString(2).getBytes(\"UTF-8\"))或者content= new String(rs.getString(2).getBytes(\"UTF-8\"),\"GBK\"),再直接使用update或者insert语句插入到数据库,即存得UTF-8

\r\n

3. 如果某个StringGBK,要转换为UTF-8,也是使用content= new String(GBKstr.getBytes(\"UTF-8\"))或者content= new String(GBKstr.getBytes(\"UTF-8\"),\"GBK\"); 如果某个StringUTF-8,要转换为GBK,应该使用new String(UTFstr.getBytes(\"GBK\"),\"UTF-8\")

\r\n

九、数据库连接方式使用缺省,即不跟参数

\r\n

1. str2=new String(GBKstr.getBytes(\"UTF-8\"),\"ISO-8859-1\"),可以将数据库里的GBK编码转换为UTF-8

\r\n

2. 读取UTF-8然后存入UTF-8,则用str1=new String(UTFstr.getBytes(),\"ISO-8859-1\")或者str1=new String(UTFstr.getBytes(\"GBK\"),\"ISO-8859-1\")

\r\n

3. 不能实现数据库里的UTF-8转换为GBK

\r\n

如果采用UTF-8的数据库连接方式或者缺省数据连接方式,那么无法将UTF-8转为GBK;而GBK的数据库连接方式可以实现UTF-8GBK的相互转换。建议大家采用GBK的数据连接方式。\r\n

\r\n

***原创文章,欢迎批评指正!***\r\n***@作者 桃源过客***\r\n***@QQ 1035136784***\r\n***@邮箱 cyutyw@126.com***

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3056, 'jsp-to-connect-access-database', 'JSP连接Access数据库', '2011-11-14 03:02:51', '2019-03-25 21:29:22', '       这些天一直在研究数据库操作,但是我的笔记本是win7旗舰版,安装SQL Server比较麻烦,因此用Access数据库演示!以下是我写的代码。要正确的使用这段代码,你需要首先在Access数据库里创建一个student.mdb(特别提示:注意不要建成.accdb,此方法对于.accdb不适用,关于.accdb我会后续介绍数据库,再建一个stu表,表里面创建两个字符型的字段,字段名分别为:username,password,然后插入几条测试数据。\r\n\r\n\"\"\r\n\r\n以下用两种方式来实现jsp连接access数据库。\r\n第一种:JSP形式\r\n复制内容到剪贴板代码:\r\n<%@page contentType=\"text/html\" import=\"java.sql.*\" pageEncoding=\"UTF-8\"%>\r\n<html>\r\n<head>\r\n<title>JSP连接Access模版!</title>\r\n</head>\r\n\r\n<body>\r\n<%try\r\n{\r\n//以下几项请自行修改\r\nClass.forName(\"sun.jdbc.odbc.JdbcOdbcDriver\");\r\n//创建数据库连接\r\nString url =\"jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=D:/NetBeansWorkplace/lyb/web/student.mdb\";\r\n//加载JDBC驱动程序,请将红色部分改成数据库的绝对路径\r\nConnection conn= DriverManager.getConnection(url,\"\",\"\");//URL、数据库用户名、密码\r\n//创建Statement\r\nStatement stmt=conn.createStatement();\r\n//执行Statement\r\n/* 数据库连接代码结束*/\r\n/* 测试数据代码开始*/\r\n/*请在数据库JSP.mdb中建立userTable表,表中建立两个字段username和password,类型为文本型*/\r\n\r\nString sql= \"select * from stu\";\r\n//请将红色部分改成数据库中的表名\r\nResultSet rs = stmt.executeQuery(sql);//处理查询结果集\r\nwhile(rs.next())\r\n{\r\nout.print(\"用户名:\" + rs.getString(\"username\"));\r\nout.print(\" 密码:\" + rs.getString(\"password\") + \"<br>\");\r\n}\r\n//红色部分为字段名称\r\nout.print(\"恭喜你!数据库连接成功!\");\r\nrs.close(); //关闭记录集对象\r\nstmt.close(); //关闭语句对象\r\nconn.close(); //关闭连接对象\r\n}\r\ncatch(Exception e){\r\nout.print(\"数据库连接错误!,错误信息如下:<br>\");\r\nout.print(e.getMessage());\r\n}\r\n//测试数据代码结束*/\r\n%>\r\n</body>\r\n</html>\r\n运行结果:\r\n\"\"\r\n\r\n第二种:JavaBean的形式。\r\n复制内容到剪贴板代码:\r\n\r\n/*\r\n作用:java连接Access数据库代码\r\nEmail:cyutyw@126.com\r\nAuthor:桃源过客\r\n*/\r\n\r\npackage conn; //导入包coon\r\nimport java.sql.*; //导入数据库操作的类\r\n\r\npublic class DBConnAccess //构造方法,初始化\r\n{\r\n\r\nprivate Connection conn; //连接对象\r\nprivate Statement stmt; //语句对象\r\nprivate ResultSet rs; //结果集对象\r\nprivate String accessdriver; //保存Access驱动程序字符串\r\nprivate String accessURL; //保存Access连接字符串\r\n\r\npublic DBConnAccess()\r\n{\r\n//Access驱动程序\r\naccessdriver = \"sun.jdbc.odbc.JdbcOdbcDriver\";\r\n//连接字符串\r\naccessURL = \"jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=\";\r\nconn = null;\r\n}\r\n\r\n//该方法从参数得到数据库路径,并加到连接字符串后面,然后再建立连接\r\npublic Connection getConnToAccess(String dbpath){\r\ntry{\r\naccessURL=accessURL+dbpath;\r\nClass.forName(accessdriver);\r\nconn = DriverManager.getConnection(accessURL);\r\n}catch(Exception e){\r\nSystem.out.println(\"操作数据库出错,请仔细检查\");\r\nSystem.err.println(e.getMessage());\r\n}\r\nreturn conn;\r\n}\r\n\r\n//关闭数据库连接\r\npublic void close()\r\n{\r\ntry{\r\nrs.close();\r\nstmt.close();\r\nconn.close();\r\n}catch(SQLException sqlexception){\r\nsqlexception.printStackTrace();\r\n}\r\n}\r\n}\r\n\r\n调用方法如下:\r\n复制内容到剪贴板代码:\r\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=gb2312\">\r\n<%@page contentType=\"text/html; charset=utf-8\" language=\"java\"\r\nimport=\"java.sql.*\" %>\r\n<jsp:useBean id=\"DBConn\" scope=\"page\" class=\"conn.DBConnAccess\"/>\r\n<%\r\n//连接Access 数据库\r\nString dbpath=\"student.mdb\"; //数据库的路径,请自行修改\r\nConnection conn=DBConn.getConnToAccess(application.getRealPath(dbpath));\r\nStatement stmt=conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);\r\nString sql=\"select * from username order by id\";\r\nString sql1=\"insert into username (uid,pwd) values(\'wsp\',\'wsp\')\";\r\nstmt.executeUpdate(sql1);\r\nResultSet rs=stmt.executeQuery(sql);\r\n\r\nwhile(rs.next()){\r\nout.print(\"用户名:\");\r\nout.print(rs.getString(\"userame\")+\" 密码:\");\r\nout.println(rs.getString(\"password\")+\"<br>\");\r\n}\r\nDBConn.close();\r\n%>\r\n

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3057, 'c-string-use', 'C++中string的使用', '2011-11-13 05:03:48', '2019-03-25 21:29:22', '使用之前必须加上#include<string>,并且在cin>>后面不能加>>endl。\r\n例如:\r\n#include<iostream>\r\n#include<string>\r\nusing namespace std;\r\nint main()\r\n{ string str;\r\ncin>>str;\r\ncout<<str;\r\nreturn 0;\r\n}\r\n\r\n\"\"\r\n

***原创文章,欢迎批评指正!***\r\n***@作者 桃源过客***\r\n***@QQ 1035136784***\r\n***@邮箱 cyutyw@126.com***

\r\n ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3059, 'java-again-learn-note-001-1-1-in-notepad-write-a-simple-helloworld-java-program', '重拾Java学习笔记001:【1.1】用Java在记事本中写一个最简单的HelloWorld程序', '2011-11-12 18:17:10', '2019-04-28 22:52:18', '

\r\n       首先要保证您已下载并成功安装好JDK,并且配置好了环境变量(关于环境变量的配置,请参考我的另一篇关于配置环境变量文章http://www.xinvalue.com/news/?118.html),如果做好了这一步,请往下看:
\r\n       在win7桌面上创建一个cd的文件夹,再创建一个HelloWorld.java的文件,复制一下内容保存,一定要将扩展名(如果隐藏了扩展名请在控制面板打开)改为.java。

\r\n

\r\n public class HelloWorld

\r\n

\r\n {

\r\n

\r\n public static void main(String args[])

\r\n

\r\n {

\r\n

\r\n System.out.println("Hello World");

\r\n

\r\n }

\r\n

\r\n
\r\n       然后按以下步骤进行:
\r\n       1.开始->运行->cmd 打开命令行

\r\n

\r\n       2.然后进入cd文件夹(具体方法请参考我的另一篇文章http://www.xinvalue.com/news/?170.html
\r\n       3.输入javac HelloWorld.java
\r\n       屏幕上命令行将是:

\r\n       C:UsersAdministratorDesktopcd> javac HelloWorld.java
\r\n       此时在cd文件夹将产生一个HelloWorld.class文件。

\r\n

\r\n
\r\n  

\r\n

\r\n       4.输入java HelloWorld
\r\n       屏幕上命令行将是:

\r\n       C:UsersAdministratorDesktopcd> java HelloWorld
\r\n       5.查看效果,屏幕上将显示:
\r\n       Hello World!

\r\n

\r\n
\r\n  

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3060, 'win7-how-to-use-cd-command-in-dos-to-enter-folder', 'win7如何利用DOS里的CD命令进入文件夹', '2011-11-12 18:05:18', '2019-11-27 22:34:00', '      DOS模式下,如要进入D盘 File文件夹,输入命令:\r\n\r\nD:加回车          其中D是盘符\r\n\r\nCD D:File   回车      其中D:File是文件夹的绝对路径\r\n\r\n      下一行提示是:\r\n\r\nD:File>这样我们就进入File文件夹了了。\r\n\r\n例如,现在我们要进入win7桌面的cd文件夹:\r\n(1)先按win+R进入运行,输入cmd进入,再输入C:;\r\n(2)输入CD C:UsersAdministratorDesktopcd。\r\n(3)Ok,现在我们已经进入桌面的cd文件夹了,如图:\r\n\r\n\"\"', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3061, 'two-jsp-design-patterns', 'JSP的两种设计模式', '2011-11-12 00:22:15', '2019-04-28 22:52:02', ' JSP设计模式包括两个:\r\n\r\n\r\n    (1)Model1,JSP+JavaBean设计模式\r\n\r\n    (2)Model2,MVC设计模式 \r\n\r\n模式一JSP+JavaBean模式\r\n\"\"\r\n\r\n    在这种模式中,JSP页面独自响应请求并将处理结果返回客户,所有的数据库操作通过JavaBean来实现。\r\n\r\n    大量地使用这种模式,常会导致在JSP页面中嵌入大量的Java代码,当需要处理的商业逻辑非常复杂时,这种情况就会变得很糟糕。大量的Java代码使得JSP页面变得非常臃肿。前端的页面设计人员稍有不慎,就有可能破坏关系到商业逻辑的代码。\r\n\r\n    这种情况在大型项目中经常出现,造成了代码开发和维护的困难,同时会导致项目管理的困难。因此这种模式只适用于中小规模的项目。\r\n\r\n模式二 MVC模式\r\n\"\"\r\n\r\n    MVC”模式即是:“Model-View-Controller”模式。在这种模式中,通过JSP技术来表现页面,通过Servlet技术来完成大量的事务处理工作,实现用户的商业逻辑。\r\n\r\n    在这种模式中,Servlet用来处理请求的事务,充当了控制器(Controller即“C”)的角色,Servlet负责响应客户对业务逻辑的请求并根据用户的请求行为,决定将哪个JSP页面发送给客户。JSP页面处于表现层,也就是视图(View即“V”)的角色。JavaBean则负责数据的处理,也就是模型(Model即“M”)的角色。\r\n\r\nMVC架构\r\n\r\n    Model-View-Controller架构模式是80年代中期在Smalltalk-80 GUI(一种经典的面向对象程序设计语言)实验室发明的。\r\n\r\n    根据MVC模式,一个软件应该将商务逻辑(Model)和显示(View)分开。分开有许多好处,最主要的有两个方面:\r\n\r\n    1、同一的商务逻辑层(Model)可能会对应多个显示层(View),如果商务逻辑层和显示层放在一起的话,再添加一个显示层的时候就会极大的增加组件的复杂性。一个商务逻辑对着两个显示层的例子是:银行的帐户的商务逻辑层对应ATM和Internet两个显示层。\r\n\r\n     2、通常情况下,每次修改显示层的时候一般并不需要修改商务逻辑层。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3067, '%e8%af%97%e6%ae%87', '诗殇', '2011-11-09 04:01:45', '2019-04-28 22:46:56', '遥远的先民城堡 \r\n\r\n承受着孤寂的风 \r\n\r\n在时光的怀里睡着了 \r\n\r\n永远睡着了\r\n\r\n \r\n当城堡被废弃 \r\n\r\n还无所谓 还有所谓 \r\n\r\n原来 \r\n\r\n我前世是一只大鸟 \r\n\r\n活着飞翔 死了逍遥 \r\n\r\n而今 \r\n\r\n我城堡里的巢 \r\n\r\n却只剩下最后一撮羽毛 \r\n\r\n那时的梦 \r\n\r\n是在一个悠远的高空 \r\n\r\n\r\n\r\n飞在天上 \r\n\r\n落在土中\r\n\r\n \r\n现在啊 \r\n\r\n我多了一群玩伴 \r\n\r\n他们 \r\n\r\n不在天空 \r\n\r\n而在地上 \r\n\r\n仿佛是在梦中 \r\n\r\n翠绿的城堡上 \r\n\r\n还有一双翅膀\r\n\r\n \r\n然而 \r\n\r\n猎人赶走了最后一只杜鹃 \r\n\r\n木工砍掉了那棵多少年前的桂树 \r\n\r\n哪怕是在梦中 \r\n\r\n我也不知那双翅膀 \r\n\r\n飘向何方 \r\n\r\n \r\n或许 \r\n\r\n多年后城墙上会有一个回望者 \r\n\r\n只独自哼唱着遥远世纪的牧歌 \r\n\r\n他想回去啊 \r\n\r\n\r\n\r\n城堡毁灭 黯然诗殇......', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3068, 'history-history-grace-11', '词史奇葩—婉约十一首', '2011-11-09 03:41:46', '2019-06-02 06:19:16', '                    生查子\r\n\r\n                     欧阳修\r\n\r\n    去年元夜时,花市灯如昼。月上柳梢头,人约黄昏后\r\n\r\n    今年元夜时,花与灯依旧。不见去年人,泪湿春衫袖。\r\n\r\n \r\n\r\n \r\n\r\n                    忆秦娥\r\n\r\n                     李白\r\n\r\n    箫声咽,秦娥梦断秦楼月。秦楼月,年年柳色,灞陵伤别。\r\n\r\n    乐游原上清秋节,咸阳古道音尘绝。音尘绝,西风残照,汉家陵阙。\r\n\r\n \r\n\r\n \r\n\r\n                  一剪梅.舟过吴江\r\n\r\n                       蒋捷\r\n\r\n    一片春愁待酒浇,江上舟摇,楼上帘招,秋娘度与泰娘娇,风也萧萧,雨也萧萧。\r\n\r\n    何时归家洗客袍,银字笙调,心字香烧。流光容易把人抛,红了樱桃,绿了芭蕉!\r\n\r\n \r\n

 

\r\n

                      蝶恋花

\r\n

                       晏殊

\r\n

    槛菊愁烟兰泣露,罗幕轻寒,燕子双飞去。明月不谙离恨苦,斜光到晓穿朱户。

\r\n

    昨夜西风凋碧树,独上高楼,望尽天涯路。欲寄彩笺兼尺素,山长水阔知何处?

\r\n

 

\r\n

 

\r\n                   蝶恋花\r\n\r\n                    柳永\r\n

    伫倚危楼风细细,望极春愁,黯黯生天际。草色烟光残照里,无言谁会凭栏意?

\r\n

    拟把疏狂图一醉,对酒当歌,强乐还无味。衣带渐宽终不悔,为伊消得人憔悴。

\r\n

 

\r\n

望江南\r\n

\r\n

    多少恨,昨夜梦魂中。还似旧时游上苑,花月正春风。

\r\n

 

\r\n

相见欢

\r\n

李煜

\r\n

    林花谢了春红,太匆匆,无奈朝来寒雨晚来风。

\r\n

    胭脂泪,留人醉,几时重?最是人生长恨水长东。

\r\n

 

\r\n

 

\r\n

蝶恋花

\r\n

苏轼

\r\n

    花褪残红青杏小,燕子飞时,绿水人家绕。枝上柳绵吹又少,天涯何处无芳草?

\r\n

    墙里秋千墙外道,墙外行人,墙里佳人笑。笑渐不闻声渐悄,多情却被无情恼。

\r\n

 

\r\n

 

\r\n

八声甘州

\r\n

柳永

\r\n

    对潇潇暮雨洒江天,一番洗清秋。渐霜风凄紧,关河冷落,残照当楼。是处红衰翠减,苒苒物华休。惟有长江水,无语东流

\r\n

    不忍登高临远,望故乡渺邈,归思难收。叹年来踪迹,何事苦淹留?想佳人妆楼颙望,误几回,天际识归舟。争知我,倚阑干处,正凭凝愁。

\r\n

 

\r\n

 

\r\n

渔父

\r\n

李煜

\r\n

    浪花有意千重雪,桃李无言一队春。一壶酒,一竿纶,世上如侬有几人?

\r\n

 

\r\n

 

\r\n

 

\r\n

苍梧谣

\r\n

蔡伸

\r\n

    天,休使圆蟾照客眠。人何在,桂影自婵娟!

\r\n

 

\r\n

 

\r\n

 

\r\n

 

\r\n

长相思令

\r\n

邓肃

\r\n

    红花飞,白花飞,郎与春风同别离,春归郎不归。

\r\n

    雨霏霏,雪霏霏,又是黄昏独掩扉,孤灯隔翠帏。

\r\n

 

\r\n

 

\r\n

 

\r\n

 

\r\n

                     长相思\r\n向滈

\r\n

    行相思,坐相思,两处相思各自知,相似更为谁?

\r\n

    朝相思,暮相思,一日相思十二时,相思无尽期!

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3084, 'autumn-autumn-rain-leaves-into-the-war', '秋风秋雨 落叶成殇', '2011-10-30 01:30:31', '2019-04-10 05:26:45', '

\r\n   秋雨夜,漆黑,我无力向窗外张望,怕触摸到我的伤心处。为什么我选择的,会是这样的凄凉,曾几次拿起电话,理智中让我又放下。按下了拨出键。可又按下……只是思念。
\r\n   
\r\n   雨中,只有我独自憨憨的轻弹着那寂寞的脚步,徘徊在柳林中,踏着那软绵绵的落叶,没有了那秋蝉余音的缭绕,只有滴落着的秋雨,掺拌着相思和眷恋,与这幽怨的夜莺在哀婉吟唱。细雨打在柳叶上,沙沙作响,滴落在头上,轻轻地滑落至脊梁,刺骨的寒意,穿心的凉,我真的只是觉得很刺激,想让它平息着满心思念的燥热。只想有人对我说,或者,我对有人说……
\r\n   
\r\n   无力,心的憔悴。提不起困意。
\r\n   
\r\n   我没有办法逃避,其实,一开始,只是热爱着生活,好奇心的驱使,尝试着生活中听到的,见到的,可我触摸不到的意境。真的有一天,不经意间的相遇,短暂的欣喜之余,剩下的却是经久不衰,流传千古的柔佳话。人世间的甜酸苦辣就是这样,轻而易举的从灶房搬到了情场。当你无节制舔舐着甜蜜,把品尝那甘甜似做膳用,不小心将禁果吞咽至囊中。想不酸,不可能。想不苦,也不罢。
\r\n   
\r\n   不惜心的疲惫,只是把情探至爱河的边沿,慢慢的沉溺着,下意识的回头,本能的搭扯者岸上的柳条。哪知,秋日的柳枝,却随着那深重的爱,悬越过河堤,陷逐至深底,被河水慢慢的吞噬者。又刑,生烹硬煮,忍受着煎熬……
\r\n   
\r\n   这爱河中,曾有过我的阳光,阳光下,我笑得灿烂。
\r\n   
\r\n   这爱河中,曾有过我的黑夜,黑夜中,我哭的凄惨。
\r\n   
\r\n   我把灿烂送给迎面的来人,让它快乐。把凄惨搂在我的怀中,独自享用,好像寂寞是我的专利,因为我割舍不下那份不该爱的爱。只能用酸涩的泪汁,冲刷着那份迟来的真情、、、心痛之余,感慨着,再不敢去触摸那爱,伤不起。
\r\n   
\r\n   秋风,秋雨,秋的深夜,不该无星无月无人伴。满心惆怅。
\r\n   
\r\n   秋思,秋念,秋的留恋,不该秋雨灌柳皮撕裂。落叶成殇。
\r\n   
\r\n  

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3088, 'website-icons-to-use', '网站图标使用方法', '2011-10-29 23:36:57', '2019-04-28 22:36:00', '在线生成ico地址\r\n\r\n[https://tool.lu/favicon/](https://tool.lu/favicon/)\r\n\r\n生成网站ICO后16∗16,保存为favicon.ico,然后上传到网站根目录。\r\n\r\nIE8及更高版本在访问网站的时候即可自动识别。为保存IE6正常显示,应该在网页源代码块内加入此代码:\r\n\r\n```html\r\n\r\n```', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3142, 'wordpress-to-bae', '关于将WordPress博客转移到百度BAE的若干问答', '2013-11-07 14:00:00', '2019-03-25 21:29:22', '【版权声明:本文转载自http://www.cmhello.com/,版权归原作者。如需转载,请务必在转载时注明原文地址。】\r\n
倡萌7月份的时候就开始申请了BAE测试,详见《在百度应用引擎(BAE)折腾WordPress》,但当时还不能伪静态,所以倡萌没有继续折腾。而在10天前,倡萌听说已经有朋友折腾出伪静态的方法,所以又折腾了一下,方法来自 hjin.me,而 免费资源部落 的小qi已经整理了比较完整的教程,你如果想折腾,可移步《百度BAE空间安装WordPress-邀请码数据库Url重写伪静态发送邮件云存储》。\r\n\r\n几天前,将倡萌软件园 完整转移到百度BAE了,主要是这个软件园已经不打算更新,但是每天都有600IP访问,所以暂时不打算关闭,只好转移,不占用我的主机。话说,转过去以后,原来的主题居然不能正常使用,所以换上了最新的Htwo主题,连LOGO都懒得换了,就那样吧。\r\n\r\n最近也有不少朋友问了些关于BAE的问题,就一起在文中回答一下吧。\r\n\r\n提示:BAE不是每个人都能折腾的,如果你不知道如何操作PhpMyadmin,没有操作过WordPress更换域名或搬家,那你最好不要折腾了。倡萌只是简单说说,不保证说的全对,也不保证人人能看懂。\r\n\r\n1、如何在 BAE搭建WordPress?\r\n\r\n前面已经给了链接,自己去看看吧,不赘述。(提示一下:安装过程,请确保你新建的BAE MySQL数据库是空的,否则可能会出现无法链接数据库的情况)\r\n\r\n2.如何将原有文章数据转移到BAE?\r\n\r\n倡萌亲自折腾发现,使用百度 BAE 的 PhpMyadmin 导入,基本是不太可能,尤其是数据库有些大的时候,而且似乎仅仅支持没有压缩的SQL文件;也不支持使用 WordPress 自身的导出导入功能。\r\n\r\n建议你使用BAE大数据库导入方法:\r\n\r\n(1)访问你自己的云数据库,按照下图点击导入\r\n\r\n(2)在你原来的PhpMyadmin导出你的数据库文件,必须为没有压缩的sql文件,然后上传到你原来的主机空间,保证可以通过http访问,然后将访问地址添加到下图中,提交\r\n\r\n(3)不要关闭上传的界面,稍等几分钟,一般就可以上传好了,登录你数据库的PhpMyadmin,如果一切就绪,恭喜你!\r\n\r\n(4)修改你在BAE的wordPress站点的 wp-config.php 的数据库信息为导入的新数据库,然后通过PhpMyadmin修改数据库的域名等信息。这时候重新刷新你的BAE站点,应该可以看到页面了。登录你的后台,将主题改为默认的,处理一下就站点的一些设置问题。比如固定连接等。\r\n\r\n3.如何将原来的图片转移到BAE?\r\n\r\n百度的图片存放是云存储的,如果你直接将图片转移到原来wordPress对应的目录,或者在云存储界面上传,那是没办法正常访问的。\r\n\r\n上面安装的时候,你应该创建了云存储的Bucket,而且上面教程中的WordPress版本,附带了一个插件:BCS Support,启用这个插件,填入你的Bucket名字。\r\n\r\n访问WP后台-媒体-添加\r\n\r\n注意,通过这里上传的图片都是直接存放在 Bucket 的根目录的,不能建文件夹装着。最后的图片地址是这样的:\r\n\r\nhttp://bcs.duapp.com/你的Bucket名称/图片文件名,\r\n\r\n比如下面的地址:\r\n\r\nhttp://bcs.duapp.com/cmblog/cmhello.com-201209001.png\r\n\r\n所以,最后你需要在PhpMyadmin里通过sql命令来批量修改原来的图片地址到新地址,尤其要注意目录的变化(非常重要)。\r\n\r\n可能要用到了sql命令:\r\n
\r\n
\r\n
    \r\n
  1. UPDATE wp_posts   
  2. \r\n
  3. SET post_content = REPLACE( post_content, \'http://www.cmhello.com/wp-content/uploads/2012/01/\', \'http://bcs.duapp.com/cmblog/\' ); 
  4. \r\n
\r\n
\r\n上面只是样例,请自己修改为你自己的,不会用的,自己参考《WordPress 使用SQL语句批量替换/修改文章信息》,还是不会的,不要折腾 BAE 啦!\r\n\r\n好了,基本思路说完了,其他的自己折腾摸索吧。
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3161, 'vs-downloads-from-vc6-to-vs2013', '史上最强最全VC6.0到VS2013全部版本下载地址', '2013-11-08 15:27:00', '2019-03-26 00:21:05', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

\r\n

Microsoft Visual Studio 6.0 下载

\r\n

\r\n

[reply]英文版360云盘下载

\r\n

http://l11.yunpan.cn/lk/sVeBLC3bhumrI

\r\n

英文版115网盘下载

\r\n

http://115.com/file/bew2qrau

\r\n

英文版迅雷下载

\r\n

http://61.138.140.18/download/jlste_nw/vs6en.iso

\r\n

FTP下载

\r\n

ftp://211.69.16.66/microsoftvisualc++6.0.zip

\r\n

汉化补丁

\r\n

http://www.verycd.com/topics/63305/

\r\n

Visual C++ 6.0 汉化补丁

\r\n

http://115.com/file/bewnatxu

\r\n

Visual C++ 6.0 with Sp6 大企业集成安装版(中文+英文)115网盘链接下载地址

\r\n

http://u.115.com/file/f81889fc2f

\r\n

[/reply]

\r\n

Microsoft Visual Studio 6.0 MSDN 下载

\r\n

\r\n

[reply]MSDN 2001 October(适合VC6的最后一个版本)

\r\n

http://www.cctry.com/thread-5422-1-1.html

\r\n

Microsoft Visual Studio 6.0 Service Pack 6 补丁:

\r\n

英文版:http://download.microsoft.com/do ... c22eed74/Vs6sp6.exe

\r\n

中文版:http://download.microsoft.com/do ... 2f497309/Vs6sp6.exe

\r\n

[/reply]

\r\n

Microsoft Visual Studio 2005 下载

\r\n

\r\n

Visual Studio 2005 Professional 官方90天试用版

\r\n

[reply]英文版:http://download.microsoft.com/do ... 05_Pro_90_Trial.img

\r\n

中文版:http://download.microsoft.com/do ... 05_Pro_90_Trial.img

\r\n

英文版电驴下载:http://www.verycd.com/topics/138840/

\r\n

[/reply]

\r\n

Visual Studio Team System 2005 Team Suite 官方90天试用版

\r\n

[reply]英文版:http://download.microsoft.com/do ... _vsts_180_Trial.img

\r\n

中文版:http://download.microsoft.com/do ... _VSTS_180_Trial.img

\r\n

[/reply]

\r\n

Microsoft Visual Studio 2008 下载

\r\n

\r\n

Visual Studio 2008 Professional 官方90天试用版

\r\n

[reply]英文版:http://download.microsoft.com/do ... rialENUX1435622.iso

\r\n

中文版:http://download.microsoft.com/do ... rialCHSX1435983.iso

\r\n

[/reply]

\r\n

Visual Studio Team System 2008 Team Suite 官方90天试用版

\r\n

[reply]英文版:http://download.microsoft.com/do ... ayTrialX1429235.iso

\r\n

中文版:微软官方分为7个压缩分卷,请全部下载之后,对任意压缩包点击右键解压即可:

\r\n

http://download.microsoft.com/do ... SX1429243.part1.exe

\r\n

http://download.microsoft.com/do ... SX1429243.part2.rar

\r\n

http://download.microsoft.com/do ... SX1429243.part3.rar

\r\n

http://download.microsoft.com/do ... SX1429243.part4.rar

\r\n

http://download.microsoft.com/do ... SX1429243.part5.rar

\r\n

http://download.microsoft.com/do ... SX1429243.part6.rar

\r\n

http://download.microsoft.com/do ... SX1429243.part7.rar

\r\n

[/reply]

\r\n

Microsoft Visual Studio 2008 Sp1 补丁微软官网下载地址

\r\n

[reply]英文版:http://download.microsoft.com/do ... 8SP1ENUX1512962.iso

\r\n

中文版:http://download.microsoft.com/do ... 8SP1CHSX1512981.iso

\r\n

[/reply]

\r\n

Microsoft Visual Studio 2010 下载

\r\n

Visual Studio 2010 Professional 试用版

\r\n

[reply]中文版:http://download.microsoft.com/do ... 2010ProTrialCHS.iso

\r\n

英文版:http://download.microsoft.com/do ... VS2010ProTrial1.iso

\r\n

[/reply]

\r\n

Visual Studio 2010 Premium 试用版

\r\n

[reply]中文版:http://download.microsoft.com/do ... 010PremTrialCHS.iso

\r\n

英文版:http://download.microsoft.com/do ... S2010PremTrial1.iso

\r\n

[/reply]

\r\n

Visual Studio 2010 Ultimate 试用版

\r\n

[reply]中文版:http://download.microsoft.com/do ... 10UltimTrialCHS.iso

\r\n

英文版:http://download.microsoft.com/do ... 2010UltimTrial1.iso

\r\n

[/reply]

\r\n

Microsoft Visual Studio 2010 Sp1 补丁微软官网下载地址

\r\n

[reply]多语言版ISO直接下载地址

\r\n

http://download.microsoft.com/do ... 0/VS2010SP1dvd1.iso

\r\n

1、Microsoft Visual Studio 6 序列号全输入1即可;

\r\n

2、Microsoft Visual Studio 2005:进入控制面板,在“添加删除”里面选择删除\"Visual Studio 2005\",然后在打开的窗口中选择最后一项“添加注册码升级到正式版”,在里面输入下面的 CD-KEY 然后点升级就OK了! CD-KEY:KYTYH-TQKW6-VWPBQ-DKC8F-HWC4J

\r\n

3、Microsoft Visual Studio 2008:方法同 Visual Studio 2005,CD-KEY 为:PYHYP-WXB3B-B2CCM-V9DX9-VDY8T

\r\n

4、Microsoft Visual Studio 2010:方法同 Visual Studio 2005,CD-KEY 为:YCFHQ-9DWCY-DKV88-T2TMH-G7BHP

\r\n

[/reply]

\r\n

另附:Visual C++ 6.0 支持的最新SDK下载地址

\r\n

\r\n

现在 VC++6.0 支持的最新 SDK 只有2个了,下载地址如下:

\r\n

For Server2003 3790.0 RTM

\r\n

[reply]

\r\n

http://www.microsoft.com/msdownl ... pdate/psdk-full.htm

\r\n

115网盘下载地址:http://u.115.com/file/f81cdead71

\r\n

[reply]

\r\n

For XPSP2 2600.2180 RTM

\r\n

[reply]

\r\n

http://www.microsoft.com/msdownl ... PSP2FULLInstall.htm

\r\n

115网盘下载地址:http://u.115.com/file/f89df02047

\r\n

XPSP2 2600.2180 RTM 安装举例

\r\n

把网页里面的10几个压缩包都下载了,总共大概 236M左右,之后解压开,完了安装,之后运行下:

\r\n

开始菜单 -> Microsoft Platform SDK for Windows XP SP2 -> Visual Studio Registration -> Register PSDK Directories with Visual Studio 就可以把 SDK 的目录注册到 VC++6.0 的 Include 里面了!

\r\n

VisualAssistX_10.7.1925_Soft711 : http://pan.baidu.com/share/link? ... 7&uk=1563813647

\r\n

注:以上地址都是微软官方或者从官方下载后上传到网盘中,所以,请大家放心下载!

\r\n

[/reply]

\r\n

Win下面注册2008的补丁

\r\n

[reply]

\r\n

VS2012_ULT_enu.iso下载(英文旗舰版) http://download.microsoft.com/do ... /VS2012_ULT_enu.iso

\r\n

VS2012_ULT_chs.iso下载(中文旗舰版) http://download.microsoft.com/do ... /VS2012_ULT_chs.iso

\r\n

VS2012 Key

\r\n

YKCW6-BPFPF-BT8C9-7DCTH-QXGWC

\r\n

RBCXF-CVBGR-382MK-DFHJ4-C69G8

\r\n

[/reply]

\r\n

微软Visual Studio 2013预览版下载页面

\r\n

\r\n

[reply]

\r\n

http://www.microsoft.com/visualstudio/chs/2013-downloads

\r\n

[/reply]

\r\n

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3177, 'spinner-simple-data-bind', 'Android中Spinner数据绑定的简单实现', '2013-11-10 14:00:00', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

Spinner在android中通常用来实现下拉列表,但可惜的是Spinner没有直接实现类似text-value这样的自动绑定功能。某些情况下,列表展示的文本并不是我们想要取得的值,这样就需要手动实现数据绑定。首先用2个数组来分别表示显示的文本和要取的值,代码如下:

  1. private final static String[] texts = {"第一页", "第二页", "第三页"};  
  2. private final static int[] values = {1, 2, 3};  
  3. private Spinner sp_start = null;  
  4. private ArrayAdapter<String> startAdapter; 

这里texts是下拉列表中显示的文本,values是根据列表选定后指定的值。接着就是实现Spinner了,代码如下:

  1. sp_start = (Spinner) findViewById(R.id.sp_start);  
  2. //绑定要显示的texts  
  3. startAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, texts);  
  4. //设置下拉列表的风格  
  5. startAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);  
  6. sp_start.setAdapter(startAdapter); 

另外,也可以用spinner.getSelectedItem().toString()来取得选定的文本,或者用spinner.getSelectedItemPosition()来取得选定文本的位置,从而可以用values[spinner.getSelectedItemPosition()]来取得对应的值。

如果你的列表数据是动态获得的。可以使用ArrayList代替数组来动态添加。

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3185, '2013%e5%b9%b410%e6%9c%8828%e6%97%a5-131711', '2013年10月28日 13:17:11', '2013-10-28 05:16:13', '2019-03-25 21:29:22', '68天,打响最后的战役。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3200, '2013%e5%b9%b410%e6%9c%8829%e6%97%a5-053024', '2013年10月29日 05:30:24', '2013-10-28 21:29:24', '2019-03-25 21:29:22', '每一分钟都要对得起自己和家人。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3205, '2013%e5%b9%b410%e6%9c%8829%e6%97%a5-055025', '2013年10月29日 05:50:25', '2013-10-28 21:49:25', '2019-03-25 21:29:22', '\r\n\r\n[int_0^{frac{pi}{2}}{xf(sin x)}dx={frac{pi}{2}}int_0^{frac{pi}{2}}{f(sin x)}dx]\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3211, '2013%e5%b9%b410%e6%9c%8829%e6%97%a5-085540', '2013年10月29日 08:55:40', '2013-10-29 00:54:40', '2019-03-25 21:29:22', 'I venture to write to you this letter,eagerly explore my request that…冒昧写信给你,希望你能帮忙实现我的请求…', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3212, '2013%e5%b9%b410%e6%9c%8829%e6%97%a5-085738', '2013年10月29日 08:57:38', '2013-10-29 00:56:38', '2019-03-25 21:29:22', 'Iwould highly appreciate it if you could help me …如果你能帮助我…我将感激不尽。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3213, '2013%e5%b9%b410%e6%9c%8829%e6%97%a5-085942', '2013年10月29日 08:59:42', '2013-10-29 00:58:43', '2019-03-25 21:29:22', '…guarantees that I meet the… requirement for… …保证了我能够满足…的要求。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3214, '2013%e5%b9%b410%e6%9c%8829%e6%97%a5-090441', '2013年10月29日 09:04:41', '2013-10-29 01:03:43', '2019-03-25 21:29:22', 'I have been an enthusiastic particpate in…which is reflectd in my resume.我曾经积极参加过…这些都在我的简历上有所反映。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3215, '2013%e5%b9%b410%e6%9c%8829%e6%97%a5-090731', '2013年10月29日 09:07:31', '2013-10-29 01:06:31', '2019-03-25 21:29:22', 'I believe my…skills make me competent for such a post.相信我的…能力能够胜任这一职位。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3216, '2013%e5%b9%b410%e6%9c%8829%e6%97%a5-090905', '2013年10月29日 09:09:05', '2013-10-29 01:08:07', '2019-03-25 21:29:22', 'Should you give me an interview,I would be very grateful.若能给予面试,不胜感激。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3217, '2013%e5%b9%b410%e6%9c%8829%e6%97%a5-091040', '2013年10月29日 09:10:40', '2013-10-29 01:09:40', '2019-03-25 21:29:22', 'Thank you for your attention,and I am looking forward for your reply.谢谢您的关注,期待回复。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3218, '2013%e5%b9%b410%e6%9c%8829%e6%97%a5-092120', '2013年10月29日 09:21:20', '2013-10-29 01:20:20', '2019-03-25 21:29:22', 'It goes without saying that it happens for some reasons.毫无疑问,这么做是有原因的。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3219, '2013%e5%b9%b410%e6%9c%8829%e6%97%a5-092257', '2013年10月29日 09:22:57', '2013-10-29 01:22:00', '2019-03-25 21:29:22', 'Aside from this,another telling example is …除了这些,另一个例子…', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3220, '2013%e5%b9%b410%e6%9c%8830%e6%97%a5-090947', '2013年10月30日 09:09:47', '2013-10-30 01:08:46', '2019-03-25 21:29:22', '中共七大确立了毛泽东思想为党的指导思想。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3221, '2013%e5%b9%b410%e6%9c%8830%e6%97%a5-091505', '2013年10月30日 09:15:05', '2013-10-30 01:14:05', '2019-03-25 21:29:22', '1930年5月,毛泽东撰写《反对本本主义》包含了毛泽东思想的活的灵魂的实事求是、群众路线、独立自主的思想。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3222, '2013%e5%b9%b410%e6%9c%8830%e6%97%a5-094305', '2013年10月30日 09:43:05', '2013-10-30 01:42:25', '2019-03-25 21:29:22', '1935年1月,遵义会议确立了以毛泽东为核心的党中央的领导。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3223, '2013%e5%b9%b410%e6%9c%8830%e6%97%a5-095239', '2013年10月30日 09:52:39', '2013-10-30 01:51:39', '2019-03-25 21:29:22', '十二大提出了建设有中国特色社会主义命题,十三大首次提出建设中国特色社会主义理论,十四大首次提出邓小平建设中国特色社会主义理论,十五大提出“邓小平理论”的概念并确立为党的指导思想。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3224, '2013%e5%b9%b410%e6%9c%8830%e6%97%a5-095934', '2013年10月30日 09:59:34', '2013-10-30 01:58:33', '2019-03-25 21:29:22', '科学发展观,第一要义是发展,核心是以人为本,基本要求是全面协调可持续,根本方法是统筹兼顾。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3225, '2013%e5%b9%b410%e6%9c%8830%e6%97%a5-101023', '2013年10月30日 10:10:23', '2013-10-30 02:09:23', '2019-03-25 21:29:22', '大革命时期,毛泽东发表了《中国社会各阶级的分析》《湖南农民运动考察报告》《国民革命与农民运动》《国民党右派分离的原因及其对革命前途的影响》,集中体现了我党把马列主义与中国实际相结合的最初成果,关于新民主主义革命基本思想的提出,标志着毛泽东思想的萌芽。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3226, '2013%e5%b9%b410%e6%9c%8830%e6%97%a5-101515', '2013年10月30日 10:15:15', '2013-10-30 02:14:15', '2019-03-25 21:29:22', '1927年党的八七会议确定了土地革命和武装起义的总方针,此后党领导了一系列武装起义创建人民军队,开始建设农村革命根据地,并展开白区斗争。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3227, '2013%e5%b9%b410%e6%9c%8830%e6%97%a5-101802', '2013年10月30日 10:18:02', '2013-10-30 02:17:03', '2019-03-25 21:29:22', '十六大报告把“与时俱进”标准明确为党的思想路线的组成部分。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3228, '2013%e5%b9%b410%e6%9c%8830%e6%97%a5-105422', '2013年10月30日 10:54:22', '2013-10-30 02:53:22', '2019-03-25 21:29:22', '十六大三个代表重要思想写入党章并作为党的指导思想。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3229, '2013%e5%b9%b410%e6%9c%8830%e6%97%a5-105544', '2013年10月30日 10:55:44', '2013-10-30 02:54:44', '2019-03-25 21:29:22', '2003年10月,党的十六届三中全会通过的,《中共中央关于完善社会主义市场经济体制若干问题的决定》第一次提出科学发展观。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3230, '131030111547', '2013年10月30日 11:15:47', '2013-10-30 03:14:47', '2019-03-25 21:29:22', '唯物史观与唯心史观的分水岭在于是否站在最广大人民的立场上,这也是判断马克思主义政党的试金石。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3236, '131102091708', '20131217090453', '2013-11-02 01:16:06', '2019-03-25 21:29:22', '终于回复正常了。原来加速乐不能开启web防火墙。\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3250, 'java-delect-url-code', 'Java自动检测URL编码', '2013-11-03 18:50:30', '2019-03-25 21:29:22', '

原由

\r\n

一般情况下,网页头信息会指定编码,可以解析header或者meta获得charset。但有时网页并没没有指定编码,这时就需要通过网页内容检测编码格式,通过调研,最好用的还是cpdetector。

\r\n

代码如下

\r\n
\r\n
 
\r\n
    \r\n
  1. package com.xinvalue.util;     
  2. \r\n
  3.     
  4. \r\n
  5. import info.monitorenter.cpdetector.io.*;     
  6. \r\n
  7.     
  8. \r\n
  9. import java.io.IOException;     
  10. \r\n
  11. import java.net.URL;     
  12. \r\n
  13. import java.nio.charset.Charset;     
  14. \r\n
  15.     
  16. \r\n
  17. /**     
  18. \r\n
  19. * Created with IntelliJ IDEA.     
  20. \r\n
  21. * User: Terwer     
  22. \r\n
  23. * Date: 13-10-27     
  24. \r\n
  25. * Time: 下午3:28     
  26. \r\n
  27. * To change this template use File | Settings | File Templates.     
  28. \r\n
  29. */    
  30. \r\n
  31. public class Test {     
  32. \r\n
  33.     public static void main(String[] args) throws IOException {     
  34. \r\n
  35.         URL url = new URL(\"http://www.xinvalue.com/\");     
  36. \r\n
  37.         CodepageDetectorProxy codepageDetectorProxy = CodepageDetectorProxy.getInstance();     
  38. \r\n
  39.     
  40. \r\n
  41.         codepageDetectorProxy.add(JChardetFacade.getInstance());     
  42. \r\n
  43.         codepageDetectorProxy.add(ASCIIDetector.getInstance());     
  44. \r\n
  45.         codepageDetectorProxy.add(UnicodeDetector.getInstance());     
  46. \r\n
  47.         codepageDetectorProxy.add(new ParsingDetector(false));     
  48. \r\n
  49.         codepageDetectorProxy.add(new ByteOrderMarkDetector());     
  50. \r\n
  51.     
  52. \r\n
  53.         Charset charset = codepageDetectorProxy.detectCodepage(url);     
  54. \r\n
  55.         System.out.println(charset.name());     
  56. \r\n
  57.     }     
  58. \r\n
  59. }    
  60. \r\n
\r\n

运行结果

\r\n

\"html-code\"

\r\n

jar包下载

\r\n

[download id=\"9\"]

\r\n

 

\r\n

[download id=\"10\"]

\r\n

 

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3252, '131104105617', '20131127214719', '2013-11-04 02:55:15', '2019-03-25 21:29:22', '\r\n网站龟速,又开启了加速乐,但是wordpress又用不了了,算了。\r\n\r\n\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3258, '1311071920', '设[X]补=a7.a6 a5··· a0 ,其中ai 取0或1, 若要X>-0.5,求a0 a1 a2 ···a7 的取值。', '2013-11-07 11:26:12', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

\r\n

【题目】\"\" ,其中\"\"取0或1, 若要X>-0.5,求\"\"的取值。

\r\n

【新价值网解析】

\r\n

(1)若\"\",则X为正数,显然\"\"取任何值均可。

\r\n

(2)若\"\",则X为负数,[X]移=\"\"

\r\n

∵ -0.5D = -0.100000B,则[-0.5D ]移=0.100000

\r\n

∴ 若要X>-0.5,即等价于[X]移> [-0.5D ]移

\r\n

\"\">0.100000,因此必须是a5··· a0不全为0。

\r\n

结论:

\r\n

1.如果a7 =0, a6··· a0取任何值均可;

\r\n

2.如果a7 =1 ,必须满足a6 =1 且a5··· a0不全为0。

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3297, 'android-chineseify-rom', 'Android汉化ROM详细教程', '2013-11-09 22:04:48', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

关于安卓汉化,说起来神秘。其实只不过是一个细活而已。下面我就以一个apk的汉化为例解来谈谈汉化的方法,实践过程中请自己揣摩!

在汉化中我们要用到apktools反编译,所以我们需要先下载ApkTool!ApkTool下载地址:apk-tool.zip

将下载好的app-tool.zip解压,然后将里面的三个文件复制到C:Windows目录

\"2\"

步骤:(实例:framework-res.apk Settings.apk Phone.apk)

1.在你放置反编那3个文件的文件夹根目录下新建三个文件夹!

中文→已有中文语言包的apk(我放置的是zckp9,众所周知国行中文最好!)

英文→待汉化的apk

完成→就是已经汉化好的apk!

2.始开提取中文apk的语言包!反编framework-res.apk得到framework-res文件夹!

\"1\"

点击打开framework-res文件夹(注意红框内的路径)提取语言包【未完待续】

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3393, 'goagent-chrome-switchsharp-ubuntu', 'goagent配合Chrome和SwitchySharp翻墙教程(Linux版)', '2014-02-03 11:29:47', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

\r\n

大天朝,幸好有杭州小子写的GoAgent。让我们可以无缓冲观看Youtube高清视频,上面书,推特。可是gihtb的项目主页上,说明文档作者只是用了Don`t Panic!来填充。让我不禁感叹,这才是大神!Ubuntu下GoAgent的安装教程如下:

\r\n

1.申请google AppID。这个网上有很多,大家可以参照网上的教程即可,此步骤略过,可以参考这个链接中的教程:https://github.com/goagent/goagent.git。

\r\n

2.安装Goagent.

\r\n

   2.1下载goagent.

\r\n

   2.2配置goagent

\r\n

   2.3安装google-chrome插件

\r\n

   2.4安装goole上传工具上传证书

\r\n

   2.5运行goagent 程序

\r\n

   2.6google-chrome浏览器设置

\r\n

3.进行优化

\r\n

 

\r\n

2安装goagent

\r\n

   2.1下载goagent.

\r\n

   
goagent在google-code上面有得下,而且网上所给的教程也多是从google-code上下载源码进行安装。但是由于天朝的防火墙会随时
更新,所以,goagent也是需要更新的。但是goagent的作者在google-code上没有维护代码包。所以最好的方法还是直接从github
上面git下来,这样后面升级也容易许多。

\r\n

    首先我们要安装git工具。通过以下命令进行安装:

\r\n
    \r\n
  1. >sudo apt-get update  
  2. \r\n
  3. >sudo apt-get install git  
  4. \r\n
\r\n

     然后进入github,goagent的主页:https://github.com/goagent/goagent,在项目主页的右下角有一个HTTPS clone URL。

\r\n

     将方框下的地址复制下来:https://github.com/goagent/goagent.git。然后执行下面的命令将github上的goagent的源码下载到我们的电脑上:

\r\n
    \r\n
  1. >sudo git clone  https://github.com/goagent/goagent.git  
  2. \r\n
\r\n

     等待程序下载完成。goagetn下载之后将会被放到你的HOME目录下。

\r\n

     2.2配置goagent

\r\n

           2.2.1进入goagent/local目录下,将你申请到的appID填入到proxy.ini中的APPID一项中去
           2.2.2上传文件配置:

\r\n

                     进入到/goagent/server/python的目录下:

\r\n
    \r\n
  1. >cd /home/你的用户名/goagent/server  
  2. \r\n
  3. >python uploader.zip  
  4. \r\n
\r\n

                      然后输入你的appID,还有你刚刚申请的app的应用专用密码,同时还有gmail等。输入完成之后,等待提示按回车,正常退出。

\r\n

      2.3安装google的goagent插件: 

\r\n

            首先在地址栏中敲入:chrome://extensions

\r\n

            进入到google
chrome的扩展程序的管理页面。同时,将goagent/local目录下的SwitchySharp.crx文件拖放到当前插件管理页面进行安装。
安装完成之后,我们                                        \"\"

\r\n

选择导入/导出选项卡,然后选择导入规则列表(由于我已经导入了规则文件,所一这里显示的是导出选项),进入到/goagent/local目录下,选择SwithyOptions.bak文件进行导入。然后就点击保存 ,就可以关闭google chrome浏览器了。

\r\n

     2.4安装上传工具上传证书。

\r\n

           如果不安装证书的话,在访Youtube等的网站有很多https网站弹出证书警示,所以需要安装证书:

\r\n
    \r\n
  1. >sudo apt-get install libnss3-tools  
  2. \r\n
  3. >certutil -d sql:$HOME/.pki/nssdb -A -t \"C,,\" -n GoAgent -i \'goagent文件夹所在的绝对路径/local/CA.crt\'  
  4. \r\n
\r\n

    安装完成之后,就基本OK了。

\r\n

  2.5google-chrome的配置:

\r\n

    安装完成之后,需要两个步骤才能够使用goagent:

\r\n

    2.5.1运行goagent客户端:

\r\n

    cd 进入到goagent/local目录。

\r\n

 

\r\n
    \r\n
  1. >cd /home/你的用户名/goagent/local  
  2. \r\n
\r\n
    \r\n
  1. #运行客户端  
  2. \r\n
\r\n
    \r\n
  1. >sudo python proxy.py  
  2. \r\n
\r\n

    2.5.2在浏览器上开启访问代理

\r\n

                   \"\"

\r\n

  点击地球,然后选择GoAgent,然后就可以进行访问啦!然后如果要访问国内的某些网站记得将其设置回来,变成直接访问。

\r\n

3.一些优化

\r\n

  安装完成之后我们需要对其进行一些优化,例如升级,例如简化命令

\r\n

 3.1自动升级

\r\n

   以后每次需要升级,都可以通过直接cd进入到goagent的目录下面,然后直接执行

\r\n
    \r\n
  1. >git pull  
  2. \r\n
\r\n

   就可以进行自动更新。这个更新的原理很先进,他只会更新我们安装版本中已经被修改的文件。所以速度会很快的。’

\r\n

 3.2设置简化命令

\r\n

   我们可以在~/.bashrc文件中添加快捷命令:

\r\n
    \r\n
  1. #运行goagent  
  2. \r\n
\r\n
    \r\n
  1. >sudo vim ~/.bashrc  
  2. \r\n
\r\n
    \r\n
  1. #在文件中添加这句命令  
  2. \r\n
  3. >alias enagae = \'sudo python /home/你的用户名/goagent/local/proxy.py\'  
  4. \r\n
\r\n

然后保存退出。然后就使用下面的命令使其生效:

\r\n

 

\r\n
    \r\n
  1. >source ~/.bashrc  
  2. \r\n
\r\n

然后就可以试着使用快捷命令enagae打开goagent了。这个命令你可以自己设置。当然在这之前,你需要关闭你已经打开的goagent客户端。Ctrl+Z。

\r\n

至此,goagent就可以带你畅游Internet无阻碍了!以后每次需要使用到的时候,就直接在终端里输入:enagae,同时打开浏览器里的插件的配置,就可以访问了。

\r\n

如果有什么问题,可以在文章下面留言,我会帮助大家解答的。

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3415, '7261', '2013年11月19日 20:51:56', '2013-11-20 04:51:56', '2019-03-25 21:29:22', '要做就全身心投入。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3424, '20131119211033', '2013年11月19日 21:10:33', '2013-11-20 05:10:33', '2019-03-25 21:29:22', '呵呵', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3460, 'iframe-full-screen', 'HTML中的iframe全屏', '2013-11-20 14:23:00', '2019-03-25 21:29:22', '【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】\r\n\r\n代码如下:\r\n
\r\n
\r\n
    \r\n
  1. <iframe id=\"ifr\" src=\"http://www.terwer.com/\" name=\"ifr\" width=\"100%\" height=\"100%\" frameborder=\"0\" scrolling=\"no\"></iframe>
  2. \r\n
\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3462, 'php-get-coming-url', 'PHP获取当前页面URL的方法', '2014-02-01 14:00:00', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

代码如下:

  1. <?php  
  2. header("Content-type: text/html; charset=utf-8");   
  3. //获取域名或主机地址   
  4. echo "域名或主机地址:".$_SERVER[\'HTTP_HOST\']."<br>"; #localhost  
  5.  
  6. //获取网页地址   
  7. echo "网页地址:".$_SERVER[\'PHP_SELF\']."<br>"; #/blog/testurl.php  
  8.  
  9. //获取网址参数   
  10. echo "网址参数:".$_SERVER["QUERY_STRING"]."<br>"; #id=5  
  11.  
  12. //获取用户代理   
  13. echo "用户代理:".$_SERVER[\'HTTP_REFERER\']."<br>";   
  14.  
  15. //获取完整的url  
  16. echo "完整的url:".\'http://\'.$_SERVER[\'HTTP_HOST\'].$_SERVER[\'REQUEST_URI\']."<br/>";  
  17. echo "完整的url2:".\'http://\'.$_SERVER[\'HTTP_HOST\'].$_SERVER[\'PHP_SELF\'].\'?\'.$_SERVER[\'QUERY_STRING\']."<br/>";  
  18. #http://localhost/blog/testurl.php?id=5  
  19.  
  20. //包含端口号的完整url  
  21. echo "包含端口号的完整url:".\'http://\'.$_SERVER[\'SERVER_NAME\'].\':\'.$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"]."<br/>";   
  22. #http://localhost:80/blog/testurl.php?id=5  
  23.  
  24. //只取路径  
  25. $url=\'http://\'.$_SERVER[\'SERVER_NAME\'].$_SERVER["REQUEST_URI"];   
  26. echo "只取路径:".dirname($url);  
  27. #http://localhost/blog  
  28. ?> 
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3536, 'wlw-invalid-response', 'Windows Live Writer出现Invalid response document returned from xmlRpc server解决方案', '2013-11-20 00:13:34', '2019-03-25 21:29:22', '【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】\r\n\r\n错误提示如下: \r\n\r\n尝试登录时发生意外错误:\r\n\r\n服务器响应无效 – 从日志服务器接收的对 blogger.getUsersBlogs 方法的响应无效:\r\n\r\nInvalid response document returned from XmlRpc server\"2013-11-20_071648\"\r\n\r\n解决方案:\r\n\r\n这个问题要修正的话,先找到class-IXR.php , 这个文件位于wp-includes文 件夹下,然后编辑打开它,查找:\r\n\r\n$length = strlen($xml);\r\n\r\n替换为:\r\n\r\n$length = strlen($xml)+3;', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3676, 'noway', '无可奉告', '2013-11-23 12:12:21', '2019-03-25 21:29:22', '
\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
网站登陆信息
鲜果网admin@xinvalue.com\r\n\r\ncbgtyw2013
微博15927766472\r\n\r\ncbgtyw2013
QQ1035136784\r\n\r\ncbgtyw2013
爱奇艺superterwer@163.com\r\n\r\ncbgtyw2020
百度superterwer\r\n\r\ncbgtyw2020
微软terwer@msn.cn\r\n\r\ncbgtyw2020
虾米cyutyw@126.com\r\n\r\ncbgtyw2020
eoeAndroidterwer\r\n\r\ncbgtyw2020
GitHubcyutyw@126.com\r\n\r\ncbgtyw2020
Wordpresscyutyw@sina.com\r\n\r\ncbgtyw2020
\r\n

木蚂蚁

\r\n
\r\n

terwer\r\ncbgtyw2020

\r\n
\r\n

pocket

\r\n
\r\n

terwer\r\ncbgtyw2020

\r\n
\r\n

csdn

\r\n
\r\n

terwer\r\ncbgtyw2020

\r\n
\r\n

iteye

\r\n
\r\n

csdn登陆

\r\n
\r\n

cnblogs

\r\n
\r\n

terwer\r\ncbgtyw2020

\r\n
\r\n

feedsky

\r\n
\r\n

admin@xinvalue.com\r\ncbgtyw2013

\r\n
\r\n

56.com

\r\n
\r\n

terwer\r\ncbgtyw2020

\r\n
\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3681, 'live', '电视直播', '2013-11-23 16:12:00', '2019-03-25 21:29:22', '', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3693, '131124214323', '高等数学131124214323', '2013-11-24 13:34:34', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

\r\n

如题。

\r\n

[ln(lim_{nto+infty} {[(1+frac{1^2}{n^2})(1+frac{2^2}{n^2})+cdots+(1+frac{n^2} {n^2}) ]}^{frac{1}{n}})\\ =lim_{nto+infty} frac{1}{n}[ln(1+frac{1^2}{n^2})+frac{1}{n}[ln(1+frac{2^2}{n^2})]+cdots+frac{1}{n}[ln(1+frac{n^2}{n^2})]\\ =sum_{i=1}^n{frac{1}{n}[ln(1+(frac{i}{n})^2)}\\ =int_0^1{ln(1+x^2)}\\ =[xln(1+x^2)]_0^1+2[x-arctanx)]_0^1\\ =ln2-2+frac{pi}{2}]

\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3719, 'wordpress-add-formula-and-align-left', 'Wordpress加入latex数学公式及MathJax居中显示的方法', '2014-02-06 06:00:35', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

\r\n

只需在主题的head.php文件中加入以下代码即可。

\r\n

使用方法:

\r\n
\r\n
<!--Latex开始-->\r\n<script type=\"text/x-mathjax-config\">\r\n MathJax.Hub.Config({\r\n        TeX: {\r\n		extensions: [\"autobold.js\"],\r\n		} ,\r\n		displayAlign: \"left\"\r\n		});\r\n		</script>\r\n<style type=\"text/css\">\r\n.MathJax_Display { text-align: left !important; }\r\n</style>\r\n<script type=\"text/javascript\" src=\"http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML\"></script>\r\n<!--Latex结束-->\r\n
\r\n

所写的公式的latex代码要以反斜杠中括号开头以反斜杠中括号结尾

\r\n

\"2013-11-24

\r\n
\r\n

例如:

\r\n
\r\n

\"2013-11-24

\r\n
\r\n

则显示为:

\r\n

[sum_{i=0}^ni=frac{n(n+1)}{2}]

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3750, 'get-youku-img', '获取优酷网、土豆网、56网的视频缩略图', '2014-02-06 14:00:00', '2019-03-25 21:29:22', '

 

\r\n

【版权声明:本文转载自http://www.linuxde.net/,版权归原作者。如需转载,请务必在转载时注明原文地址。】

\r\n
\r\n

获取优酷网视频缩略图

\r\n

优酷官方给出了API,所以很容易得到想要的缩略图,原视频地址:http://v.youku.com/v_show/id_XMjIwNDg2NjU2.html

\r\n

地址栏输入以下:http://v.youku.com/player/getPlayList/VideoIDS/XMjIwNDg2NjU2/timezone/+08/version/5/source/out?password=&ran=2513&n=3,就可以的看到输出的json内容。

\r\n

因此重点在于得到:VideoIDS/后面的这串字符XMjIwNDg2NjU2

\r\n
\r\n
 
\r\n
    \r\n
  1. // 这段正则是来获取优酷的id,出处在 /wp-content/languages/zh_CN.php,同样56网、土豆都可以找到  
  2. \r\n
  3. preg_match(\"#https?://v.youku.com/v_show/id_(?<video_id>[a-z0-9_=-]+)#i\", $url, $matches);  
  4. \r\n
  5. $cnt = count($matches);  
  6. \r\n
  7. if ($cnt>0){  
  8. \r\n
  9. $link = \"http://v.youku.com/player/getPlayList/VideoIDS/{$matches[\'video_id\']}/timezone/+08/version/5/source/out?password=&ran=2513&n=3\";  
  10. \r\n
  11. }else{  
  12. \r\n
  13. return false;  
  14. \r\n
  15. }  
  16. \r\n
  17.  
  18. \r\n
  19. // 这一段是用来解析json数据,如果想跨域用js来取,这个表示压力好大  
  20. \r\n
  21. $ch=@curl_init($link);  
  22. \r\n
  23. @curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);  
  24. \r\n
  25. $cexecute=@curl_exec($ch);  
  26. \r\n
  27. @curl_close($ch);  
  28. \r\n
  29.  
  30. \r\n
  31.  
  32. \r\n
  33. if ($cexecute) {  
  34. \r\n
  35. $result = json_decode($cexecute,true);  
  36. \r\n
  37. $json = $result[\'data\'][0];  
  38. \r\n
  39.  
  40. \r\n
  41. $data[\'img\'] = $json[\'logo\'];    // 视频缩略图  
  42. \r\n
  43. $data[\'title\'] = $json[\'title\']; //标题啦  
  44. \r\n
  45. $data[\'url\'] = $url;  
  46. \r\n
  47. $data[\'swf\'] = \"http://player.youku.com/player.php/sid/{$matches[\'video_id\']}/v.swf\"; // 视频地址  
  48. \r\n
  49.  
  50. \r\n
  51. return $data;  
  52. \r\n
  53. } else {  
  54. \r\n
  55. return false;  
  56. \r\n
  57. \r\n
\r\n

获取土豆网视频缩略图

\r\n

同上,也是土豆官方给出了api,所以很容易得到想要的缩略图。地址栏输入:http://api.tudou.com/v3/gw?method=item.info.get&appKey=myKey&format=json&itemCodes=gTrKrJYVFvs就可以的看到输出的json内容。

\r\n

因此重点在于得到:itemCodes= gTrKrJYVFvs,代码直接看demo吧:http://mufeng.me/tudou

\r\n

获取56网视频缩略图

\r\n

56网的api参考这里: http://dev.56.com/wiki/index.PHP?doc-view-20,官方的sdk给出了关于sign的计算,省了很多事。

\r\n
\r\n

 

\r\n

vd

\r\n
\r\n

 

\r\n
1.// 这段正则是来获取优酷的id,出处在 /wp-content/languages/zh_CN.php,同样56网、土豆都可以找到\r\n2.preg_match(\"#https?://v.youku.com/v_show/id_(?<video_id>[a-z0-9_=-]+)#i\", $url, $matches);\r\n3.$cnt = count($matches);\r\n4.if ($cnt>0){\r\n5.$link = \"http://v.youku.com/player/getPlayList/VideoIDS/{$matches[\'video_id\']}/timezone/+08/version/5/source/out?password=&ran=2513&n=3\";\r\n6.}else{\r\n7.return false;\r\n8.}\r\n
\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3769, 'wordpress-view-after-comment', 'WordPress博客评论和回复可见实现方法', '2014-02-08 06:00:32', '2019-03-25 21:29:22', '
\r\n
\r\n

【版权声明:本文转载自http://zmingcx.com/,版权归原作者。如需转载,请务必在转载时注明原文地址。】

\r\n

之前帮别人测试评论可见功能,并在上一篇文章《为WordPress添加文章字数统计》中试用一下,感觉还是很不错的实用功能,可以增加一下访客的评论积极性,也可能会增加一大堆无用的垃圾留言,在论坛上很常见的功能,用多了可能让人产生厌恶。不过很多童鞋对此很感兴趣,所以把实现方法贴过来。

\r\n

下面再说说不用插件的实现方法,该方法原始代码应该是出自:乱了感觉

\r\n

原始代码有个缺点即使是博主或者站长,也需要评论之后才能够看到隐藏的内容,所以又有人对该代码进行了改进。代码具体出处未知,有人认领请告知。

\r\n

代码及效果

\r\n

把下面代码加到主题functions.php文件中:[reply]

\r\n
    \r\n
  1. <?php  
  2. \r\n
  3. //回复可见  
  4. \r\n
  5. function reply_to_read($atts$content=null) {    
  6. \r\n
  7.         $hide_notice = \'<div style=\"text-align:center;border:1px dashed #FF9A9A;padding:8px;margin:10px auto;color:#FF6666;\">温馨提示:此处内容需要<a href=\"\'. get_permalink().\'#respond\" title=\"评论本文\">评论本文</a>后,<a href=\"javascript:window.location.reload();\" title=\"刷新\">刷新本页</a>才能查看。</div>\';      
  8. \r\n
  9.         extract(shortcode_atts(array(\"notice\" =>$hide_notice), $atts));     
  10. \r\n
  11.         $email = null;     
  12. \r\n
  13.         $user_ID = (int) wp_get_current_user()->ID;     
  14. \r\n
  15.         if ($user_ID > 0) {     
  16. \r\n
  17.             $email = get_userdata($user_ID)->user_email;     
  18. \r\n
  19.             //对博主直接显示内容     
  20. \r\n
  21.             $admin_email = \"cbgtyw@gmail.com\"//博主Email     
  22. \r\n
  23.             if ($email == $admin_email) {     
  24. \r\n
  25.                 return $content;     
  26. \r\n
  27.             }     
  28. \r\n
  29.         } else if (isset($_COOKIE[\'comment_author_email_\' . COOKIEHASH])) {     
  30. \r\n
  31.             $email = str_replace(\'%40\', \'@\', $_COOKIE[\'comment_author_email_\' . COOKIEHASH]);     
  32. \r\n
  33.         } else {     
  34. \r\n
  35.             return $notice;     
  36. \r\n
  37.         }     
  38. \r\n
  39.         if (emptyempty($email)) {     
  40. \r\n
  41.             return $notice;     
  42. \r\n
  43.         }     
  44. \r\n
  45.         global $wpdb;     
  46. \r\n
  47.         $post_id = get_the_ID();     
  48. \r\n
  49.         $query = \"SELECT `comment_ID` FROM {$wpdb->comments} WHERE `comment_post_ID`={$post_id} and `comment_approved`=\'1\' and `comment_author_email`=\'{$email}\' LIMIT 1\";     
  50. \r\n
  51.         if ($wpdb->get_results($query)) {     
  52. \r\n
  53.             return do_shortcode($content);     
  54. \r\n
  55.         } else {     
  56. \r\n
  57.             return $notice;     
  58. \r\n
  59.         }     
  60. \r\n
  61.     }     
  62. \r\n
  63.       
  64. \r\n
  65.     add_shortcode(\'reply\', \'reply_to_read\');    
  66. \r\n
  67. ?>  
  68. \r\n
\r\n

[/reply]自行修改其中的博主Email地址。

\r\n

使用方法

\r\n

编辑文章时添加:

\r\n

[@reply]评论可见的内容[@/reply]  

\r\n

或者

\r\n

[@reply notice=\"自定义的提示信息\"]评论可见的内容[@/reply]  

\r\n

提示:使用时去掉其中的@

\r\n

效果演示:为WordPress添加文章字数统计

\r\n
\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3895, '20131127-212932', '20131127214638', '2013-11-27 13:29:32', '2019-03-25 21:29:22', '切记,安卓手机与服务器进行参数传递时要用URLencoder进行编码。\r\n\r\n\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3899, '20131127214804', '20131127214804', '2013-11-27 13:41:14', '2019-03-25 21:29:22', '开始新的奋斗。\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3900, '20131127220317', '20131127221301', '2013-11-27 13:56:28', '2019-03-25 21:29:22', '\r\n[Gamma函数 int_0^{+infty}x^{alpha-1}e^x=Gamma(alpha)]\r\n\r\n\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3916, 'contact-me', '联系方式', '2013-11-27 17:12:50', '2019-03-25 21:29:22', '

[noway]\r\n

笔者的联系方式:

\r\n

微博: @LeaveBugsAway

\r\n

邮箱:cbgtyw@gmail.com

\r\n

QQ:1035136784(非技术问题勿扰)
\r\n[/noway]

\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3920, 'php-smtp', 'php中通过smtp发邮件的类', '2014-02-08 14:00:00', '2019-03-25 21:29:22', '

【版权声明:本文转载自脚本之家,版权归原作者。如需转载,请务必在转载时注明原文地址。】

smtp.php

  1. <?php   
  2. class smtp   
  3. {   
  4.     /* Public Variables */   
  5.     var $smtp_port;   
  6.     var $time_out;   
  7.     var $host_name;   
  8.     var $log_file;   
  9.     var $relay_host;   
  10.     var $debug;   
  11.     var $auth;   
  12.     var $user;   
  13.     var $pass;   
  14.  
  15.     /* Private Variables */    
  16.     var $sock;   
  17.  
  18.     /* Constractor */   
  19.     function smtp($relay_host = "", $smtp_port = 25,$auth = false,$user,$pass)   
  20.     {   
  21.         $this->debug = FALSE;   
  22.         $this->smtp_port = $smtp_port;   
  23.         $this->relay_host = $relay_host;   
  24.         $this->time_out = 30; //is used in fsockopen()    
  25.         $this->auth = $auth;//auth   
  26.         $this->user = $user;   
  27.         $this->pass = $pass;   
  28.         $this->host_name = "localhost"; //is used in HELO command    
  29.         $this->log_file = "";   
  30.         $this->sock = FALSE;   
  31. }   
  32.  
  33.     /* Main Function */   
  34.     function sendmail($to, $from, $subject = "", $body = "", $mailtype, $cc = "", $bcc = "", $additional_headers = "")   
  35.     {   
  36.         $mail_from = $this->get_address($this->strip_comment($from));   
  37.         $body = ereg_replace("(^|(rn))(.)", "1.3", $body);   
  38.         $header .= "MIME-Version:1.0rn";   
  39.         if($mailtype=="HTML")   
  40.         {   
  41.             $header .= "Content-Type:text/htmlrn";   
  42.         }   
  43.         $header .= "To: ".$to."rn";   
  44.         if ($cc != "")    
  45.         {   
  46.             $header .= "Cc: ".$cc."rn";   
  47.         }   
  48.         $header .= "From: $from<".$from.">rn";   
  49.         $header .= "Subject: ".$subject."rn";   
  50.         $header .= $additional_headers;   
  51.         $header .= "Date: ".date("r")."rn";   
  52.         $header .= "X-Mailer:By Redhat (PHP/".phpversion().")rn";   
  53.         list($msec, $sec) = explode(" ", microtime());   
  54.         $header .= "Message-ID: <".date("YmdHis", $sec).".".($msec*1000000).".".$mail_from.">rn";   
  55.         $TO = explode(",", $this->strip_comment($to));   
  56.  
  57.         if ($cc != "")    
  58.         {   
  59.             $TO = array_merge($TO, explode(",", $this->strip_comment($cc)));   
  60.             }   
  61.         if ($bcc != "")    
  62.         {   
  63.             $TO = array_merge($TO, explode(",", $this->strip_comment($bcc)));   
  64.         }   
  65.         $sent = TRUE;   
  66.         foreach ($TO as $rcpt_to)    
  67.         {   
  68.             $rcpt_to = $this->get_address($rcpt_to);   
  69.             if (!$this->smtp_sockopen($rcpt_to))    
  70.             {   
  71.                 $this->log_write("Error: Cannot send email to ".$rcpt_to."n");   
  72.                 $sent = FALSE;   
  73.                 continue;   
  74.             }   
  75.             if ($this->smtp_send($this->host_name, $mail_from, $rcpt_to, $header, $body))    
  76.             {   
  77.                 $this->log_write("E-mail has been sent to <".$rcpt_to.">n");   
  78.             }    
  79.             else    
  80.             {   
  81.                 $this->log_write("Error: Cannot send email to <".$rcpt_to.">n");   
  82.                 $sent = FALSE;   
  83.             }   
  84.             fclose($this->sock);   
  85.             $this->log_write("Disconnected from remote hostn");   
  86.         }   
  87.         return $sent;   
  88.     }   
  89.  
  90.     /* Private Functions */   
  91.     function smtp_send($helo, $from, $to, $header, $body = "")   
  92.     {   
  93.         if (!$this->smtp_putcmd("HELO", $helo))    
  94.         {   
  95.             return $this->smtp_error("sending HELO command");   
  96.         }   
  97.  
  98.         #auth   
  99.         if($this->auth)   
  100.         {   
  101.             if (!$this->smtp_putcmd("AUTH LOGIN", base64_encode($this->user)))    
  102.             {   
  103.                 return $this->smtp_error("sending HELO command");   
  104.             }   
  105.             if (!$this->smtp_putcmd("", base64_encode($this->pass)))    
  106.             {   
  107.                 return $this->smtp_error("sending HELO command");   
  108.             }   
  109.         }   
  110.         if (!$this->smtp_putcmd("MAIL", "FROM:<".$from.">"))    
  111.         {   
  112.             return $this->smtp_error("sending MAIL FROM command");   
  113.         }   
  114.         if (!$this->smtp_putcmd("RCPT", "TO:<".$to.">"))    
  115.         {   
  116.             return $this->smtp_error("sending RCPT TO command");   
  117.         }   
  118.         if (!$this->smtp_putcmd("DATA"))   
  119.         {   
  120.             return $this->smtp_error("sending DATA command");   
  121.         }   
  122.         if (!$this->smtp_message($header, $body))    
  123.         {   
  124.             return $this->smtp_error("sending message");   
  125.         }   
  126.         if (!$this->smtp_eom())   
  127.         {   
  128.             return $this->smtp_error("sending <CR><LF>.<CR><LF> [EOM]");   
  129.         }   
  130.         if (!$this->smtp_putcmd("QUIT"))    
  131.         {   
  132.             return $this->smtp_error("sending QUIT command");   
  133.         }   
  134.         return TRUE;   
  135.     }   
  136.  
  137.     function smtp_sockopen($address)   
  138.     {   
  139.         if ($this->relay_host == "")    
  140.         {   
  141.             return $this->smtp_sockopen_mx($address);   
  142.         }    
  143.         else   
  144.         {   
  145.             return $this->smtp_sockopen_relay();   
  146.         }   
  147.     }   
  148.  
  149.     function smtp_sockopen_relay()   
  150.     {   
  151.         $this->log_write("Trying to ".$this->relay_host.":".$this->smtp_port."n");   
  152.         $this->sock = @fsockopen($this->relay_host, $this->smtp_port, $errno, $errstr, $this->time_out);   
  153.         if (!($this->sock && $this->smtp_ok()))    
  154.         {   
  155.             $this->log_write("Error: Cannot connenct to relay host ".$this->relay_host."n");   
  156.             $this->log_write("Error: ".$errstr." (".$errno.")n");   
  157.             return FALSE;   
  158.         }   
  159.         $this->log_write("Connected to relay host ".$this->relay_host."n");   
  160.         return TRUE;;   
  161.     }   
  162.  
  163.     function smtp_sockopen_mx($address)   
  164.     {   
  165.         $domain = ereg_replace("^.+@([^@]+)$", "1", $address);   
  166.         if (!@getmxrr($domain, $MXHOSTS))    
  167.         {   
  168.             $this->log_write("Error: Cannot resolve MX "".$domain.""n");   
  169.             return FALSE;   
  170.         }   
  171.         foreach ($MXHOSTS as $host)    
  172.         {   
  173.             $this->log_write("Trying to ".$host.":".$this->smtp_port."n");   
  174.             $this->sock = @fsockopen($host, $this->smtp_port, $errno, $errstr, $this->time_out);   
  175.             if (!($this->sock && $this->smtp_ok()))    
  176.             {   
  177.                 $this->log_write("Warning: Cannot connect to mx host ".$host."n");   
  178.                 $this->log_write("Error: ".$errstr." (".$errno.")n");   
  179.                 continue;   
  180.             }   
  181.             $this->log_write("Connected to mx host ".$host."n");   
  182.             return TRUE;   
  183.         }   
  184.         $this->log_write("Error: Cannot connect to any mx hosts (".implode(", ", $MXHOSTS).")n");   
  185.         return FALSE;   
  186.     }   
  187.  
  188.     function smtp_message($header, $body)   
  189.     {   
  190.         fputs($this->sock, $header."rn".$body);   
  191.         $this->smtp_debug("> ".str_replace("rn", "n"."> ", $header."n> ".$body."n> "));   
  192.         return TRUE;   
  193.     }   
  194.  
  195.     function smtp_eom()   
  196.     {  \r\n; 
  197.         fputs($this->sock, "rn.rn");   
  198.         $this->smtp_debug(". [EOM]n");   
  199.         return $this->smtp_ok();   
  200.     }   
  201.  
  202.     function smtp_ok()   
  203.     {   
  204.         $response = str_replace("rn", "", fgets($this->sock, 512));   
  205.         $this->smtp_debug($response."n");   
  206.         if (!ereg("^[23]", $response))    
  207.         {   
  208.             fputs($this->sock, "QUITrn");   
  209.             fgets($this->sock, 512);   
  210.             $this->log_write("Error: Remote host returned "".$response.""n");   
  211.             return FALSE;   
  212.         }   
  213.         return TRUE;   
  214.     }   
  215.  
  216.     function smtp_putcmd($cmd, $arg = "")   
  217.     {   
  218.         if ($arg != "")    
  219.         {   
  220.             if($cmd=="")    
  221.             {   
  222.                 $cmd = $arg;   
  223.             }   
  224.             else   
  225.             {   
  226.                 $cmd = $cmd." ".$arg;   
  227.             }   
  228.         }   
  229.         fputs($this->sock, $cmd."rn");   
  230.         $this->smtp_debug("> ".$cmd."n");   
  231.         return $this->smtp_ok();   
  232.     }   
  233.  
  234.     function smtp_error($string)   
  235.     {   
  236.         $this->log_write("Error: Error occurred while ".$string.".n");   
  237.         return FALSE;   
  238.     }   
  239.  
  240.     function log_write($message)   
  241.     {   
  242.         $this->smtp_debug($message);   
  243.         if (\r\n$this->log_file == "")   
  244.         {   
  245.             return TRUE;   
  246.         }   
  247.         $message = date("M d H:i:s ").get_current_user()."[".getmypid()."]: ".$message;   
  248.         if (!@file_exists($this->log_file) || !($fp = @fopen($this->log_file, "a")))    
  249.         {   
  250.             $this->smtp_debug("Warning: Cannot open log file "".$this->log_file.""n");   
  251.             return FALSE;;   
  252.         }   
  253.         flock($fp, LOCK_EX);   
  254.         fputs($fp, $message);   
  255.         fclose($fp);   
  256.         return TRUE;   
  257.     }   
  258.  
  259.     function strip_comment($address)   
  260.     {   
  261.         $comment = "([^()]*)";   
  262.         while (ereg($comment, $address))    
  263.         {   
  264.             $address = ereg_replace($comment, "", $address);   
  265.         }   
  266.         return $address;   
  267.     }   
  268.  
  269.     function get_address($address)   
  270.     {   
  271.         $address = ereg_replace("([ trn])+", "", $address);   
  272.         $address = ereg_replace("^.*<(.+)>.*$", "1", $address);   
  273.         return $address;   
  274.     }   
  275.  
  276.     function smtp_debug($message)   
  277.     {   
  278.         if ($this->debug)    
  279.         {   
  280.             echo $message;   
  281.         }   
  282.     }   
  283.  
  284. }   
  285. ?>  

测试代码

  1. <?php  
  2. require("smtp.php");  
  3. $name=$_POST[\'name\'];  
  4. ##########################################   
  5. $smtpserver = "smtp.qq.com";//SMTP服务器   
  6. $smtpserverport = 25;//SMTP服务器端口   
  7. $smtpusermail = "cbgtyw@qq.com";//SMTP服务器的用户邮箱   
  8. $smtpemailto = "cbgtyw@gmail.com";//发送给谁   
  9. $smtpuser = "cbgtyw@qq.com";//SMTP服务器的用户帐号   
  10. $smtppass = "8888888888";//SMTP服务器的用户密码   
  11. $mailsubject = "来自博客读者的邮件";//邮件主题   
  12. $mailbody = $_POST[\'message\'];//邮件内容   
  13. $mailtype = "HTML";//邮件格式(HTML/TXT),TXT为文本邮件   
  14. ##########################################   
  15. $smtp = new smtp($smtpserver,$smtpserverport,true,$smtpuser,$smtppass);//这里面的一个true是表示使用身份验证,否则不使用身份验证.   
  16. $smtp->debug = FALSE;//是否显示发送的调试信息   
  17. $smtp->sendmail($smtpemailto, $smtpusermail, $mailsubject, $mailbody, $mailtype);   
  18. echo \'OK \'.$name.\', 您的邮件已发送。\';   
  19. ?> 
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3934, '20131128065306', '20131128065306', '2013-11-27 22:46:15', '2019-03-25 21:29:22', '如果分母的次数是分子的两倍,且分子是乘积,则此多元函数无极限。若次数一样,则极限为零。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3935, '20131128072522', '20131128072522', '2013-11-27 23:18:32', '2019-03-25 21:29:22', '生命不息,奋斗不止。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3936, '20131128074305', '20131128074305', '2013-11-27 23:36:14', '2019-03-25 21:29:22', '线性代数的两大核心问题,方程组的解和矩阵对角化。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3939, '20131129132205', '20131129132205', '2013-11-29 05:15:10', '2019-03-25 21:29:22', '从f到f\'往往使用拉格朗日,从f\'到f往往使用牛顿莱布尼茨公式。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (3941, 'php-string-contains', 'php判断字符串中是否包含某字符串', '2014-02-09 14:00:00', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

代码如下

[code lang="php" ]function checkstr($str,$needle){\r\n  //$needle = "a";//判断是否包含a这个字符\r\n  $tmparray = explode($needle,$str);\r\n  if(count($tmparray)>1){\r\n      return true;\r\n   } else{\r\n     return false;\r\n  }\r\n[/code]
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4042, '20131202020021', '20131202020021', '2013-12-01 18:00:21', '2019-03-25 21:29:22', '要多使用String.replace和String.Format少用字符串重载 运算符。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4068, 'wp-get-current-plugin-index', 'wordpress获取当前插件所在的目录', '2014-02-11 14:00:00', '2019-03-25 21:29:22', '

【版权声明:本文转载自博客园,版权归原作者。如需转载,请务必在转载时注明原文地址。】

\r\n

例如,hello.php插件放在/wp-content/plugins/hello/文件夹中,那么要想得到/wp-content/plugins/hello/字符串,可以使用如下的形式:

\r\n
< ?php echo WP_PLUGIN_URL."/".dirname(plugin_basename(__FILE__))."/"; ?>
\r\n
\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4072, 'wp-add-css-js', 'wordpress正确加载JS文件与css文件的方式', '2014-02-12 14:00:00', '2019-03-25 21:29:22', '

【版权声明:本文转载自http://www.54ux.com,版权归原作者。如需转载,请务必在转载时注明原文地址。】

错误方式

wordpress中提供了wp_head钩子来帮助我们在页面的头部添加指定的头部消息,比如常见的关键词与描述,很多人也同样会使用这种方式来添加站点的外部样式文件与脚本文件,添加代码如下:

  1. <?php     
  2. add_action(\'wp_head\', \'wpb_bad_script\');     
  3. function wpb_bad_script() {     
  4. echo \'<script type="text/javascript" src="http://www.54ux.com/wp-content/themes/d-simple/js/sidenav.js">\'; //添加js文件     
  5. }     
  6. ?>    

这种方式虽然使用简单,但是非常不推荐使用,这种加载方式容易造成wordpress脚本的冲突。

wordpress脚本排队系统

介绍

wordpress在全球拥有强大的开发社群,很多人都非常积极的参与到wordpress的主题与插件的开发当中,并且可以免费使用,为了防止各个开发者开发的插件在使用过程总出现脚本冲突的问题,wordpress提供了一个非常强大的脚本加载函数wp_enqueue_script,通过这个函数,我们可以告诉wordpress在哪加载脚本,脚本依赖哪些框架,而且该函数在利用内置的JavaScript库时,可以避免多次加载同一个脚本。这有助于减少页面加载时间,以及避免与其他主题和插件冲突。

使用实例

wordpress正确加载脚本的使用很简单,代码如下:

  1. <?php  
  2.  
  3. function wpb_adding_scripts() {  
  4. wp_register_script(\'my_amazing_script\', plugins_url(\'amazing_script.js\', __FILE__), array(\'jquery\'),\'1.1\', true);  
  5. wp_enqueue_script(\'my_amazing_script\');  
  6. }  
  7.  
  8. add_action( \'wp_enqueue_scripts\', \'wpb_adding_scripts\' );    
  9. ?> 

你可以将以上代码放入你的插件文件中或者你主题的functions.php文件。

说明:

实例中我们首先通过函数wp_register_script(),这个函数接收5个参数:

  1. $handle 
  2. (string) (必须) 脚本名称. 名称必须唯一在之后函数 wp_enqueue_script() 会使用到该名称.  
  3. Default: None  
  4. $src 
  5. (string) (必须) 脚本路径,可以使用绝对路径。  
  6. Default: None  
  7. $deps 
  8. (array) (可选) 脚本依赖包,依赖包会在脚本加载之前预先加载。  
  9. Default: array()  
  10. $ver 
  11. (string) (可选)脚本版本控制。  
  12. Default: false  
  13. $in_footer 
  14. (boolean) (可选) 定义脚本的位置,如果为true脚本会在页面底部加载,默认在head头部加载。  
  15. Default: false 

当我们使用wp_register_script()函数注册脚本文件后,就可以使用函数wp_enqueue_script()函数来加载该注册的脚本文件。

也许有人会问我们为什么不直接加载脚本文件,而是先注册后加载,这不是多此一举吗。其实这主要是为了站点其他开发者在其他插件或者主题总方便引用你的核心脚本文件。

wordpress如何加载CSS样式文件

wordpress css样式文件的加载与以上介绍的脚本文件加载方式是一样的,如下实例:

  1. <?php  
  2. function wpb_adding_styles() {  
  3. wp_register_script(\'my_stylesheet\', plugins_url(\'my-stylesheet.css\', __FILE__));  
  4. wp_enqueue_script(\'my_stylesheet\');  
  5. }  
  6.  
  7. add_action( \'wp_enqueue_scripts\', \'wpb_adding_styles\' );    
  8. ?> 

以上实例总我们同样了用了wp_register_script钩子来加载样式文件。

实例中我们使用了plugins_url()来获取样式文件的路径,这个一般在插件开发过程中使用的居多,如果我们是主题中开发使用到wp_register_script()函数则可以使用get_template_directory_uri()来获取样式文件路径,如果是子主题中使用,则可以使用函数get_stylesheet_directory_uri()来获取路径,实例如下:

  1. <?php  
  2.  
  3. function wpb_adding_scripts() {  
  4. wp_register_script(\'my_amazing_script\', get_template_directory_uri() . \'/js/amazing_script.js\', array(\'jquery\'),\'1.1\', true);  
  5. wp_enqueue_script(\'my_amazing_script\');  
  6. }  
  7.  
  8. add_action( \'wp_enqueue_scripts\', \'wpb_adding_scripts\' );    
  9. ?>  

通过以上的分析,希望对大家对wordpress添加Javascript文\r\n件与css文件有新的认知,如果还有不清楚的童鞋,也可以留言。

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4133, 'wp-remove-copyright', '如何去除wordpress后台管理底部“感谢使用 WordPress 进行创作”字样', '2014-02-14 14:00:00', '2019-03-25 21:29:22', '

【版权声明:本文转载自http://www.dosxp.com,版权归原作者。如需转载,请务必在转载时注明原文地址。】

很多朋友问wordpress如何去除,其实不建议大家去除,因为WP是个很好的开源程序,保留一下人家的版权也是应该的哦,下面只说下方法,建议大家保留哦。

方法如下

找到网站目录wp-admin/admin-footer.php 删除下面代码:

  1. <p id="footer-left" class="alignleft"><?php  
  2. echo apply_filters( \'admin_footer_text\', \'<span id="footer-thankyou">\' . __( \'Thank you for creating with <a href="http://wordpress.org/">WordPress</a>.\' ) . \'</span>\' );  
  3. ?></p>   
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4139, 'wp-post-count', 'WordPress中文博客文章字数统计代码', '2014-02-14 16:00:00', '2019-03-25 21:29:22', '

【版权声明:本文转载自http://zmingcx.com,版权归原作者。如需转载,请务必在转载时注明原文地址。】

方法如下

首先把下面代码加到functions.php文件中。( 注:HotNews主题加到“//全部结束”前面 )[reply]

    1. //字数统计   
    2. function count_words ($text) {     
    3. global $post;     
    4. if ( \'\' == $text ) {     
    5. $text = $post->post_content;     
    6. if (mb_strlen($output, \'UTF-8\') < mb_strlen($text, \'UTF-8\')) $output .= \'本文共\' . mb_strlen(preg_replace(\'/s/\',\'\',html_entity_decode(strip_tags($post->post_content))),\'UTF-8\') . \'个字\';     
    7. return $output;     
    8. }     
    9. }   

[/reply]再把调用统计代码加到自己认为适合的位置。

    1. <?php echo count_words ($text); ?>   

经测试对中文统计没有什么问题,英文统计的是字母。

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4188, '20131204024706', '20131204024706', '2013-12-03 18:39:57', '2019-03-25 21:29:22', '任何时候都不要浮躁。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4209, 'get-weiyun-link-api', '获取微云文件网盘外直链永久下载地址的API接口', '2013-12-05 08:00:00', '2019-03-25 21:29:22', '

[copy]http://www.ncnjc.com/get-micro-cloud-network-disk-files-downloaded-outside-linear-permanent-address-api-interface.html[/copy]

\r\n

概述

\r\n

\"2013-12-06_001913\"

\r\n

微云是腾讯公司旗下的一个网盘服务,目前也是空间最大(10T容量免费领取,1T=1024G,10T=10240G),上传的文件最大可以上传“32G”。我现在用这种方法只适合购买有虚拟主机并支持.php脚本的空间,这样才能实现获取到微云网盘外直链永久下载地址。

\r\n

代码

\r\n

复制以下代码:

\r\n
[code lang=\"php\" ]<?php\r\n//最后更新时间:2013-12-12\r\n//构造微云分享地址\r\npreg_match(\'|/.+/(w+).|\', $_SERVER[\'REQUEST_URI\'], $res);\r\n$key = $res ? $res[1] : exit(\"Url format error!\");\r\n$url = $referer = \"http://share.weiyun.com/$key\";\r\n\r\n//获取源码,匹配出下载地址\r\n$src = curl_get_contents($url, \"\");\r\npreg_match(\'|shareInfo = (.*);|Ui\', $src, $res);\r\n$json = $res ? json_decode($res[1]) : exit(\"Can not get shareInfo!\");\r\n\r\n//拼接歌曲链接\r\n$songurl = implode(\"\", array(\r\n\"http://\".$json->dl_svr_host,\r\n\":\".$json->dl_svr_port,\r\n\"/ftn_handler\",\r\n\"/\".$json->dl_encrypt_url,\r\n\"?fname=\".urlencode($json->filename),\r\n));\r\nheader(\"Location: $songurl\");\r\n\r\n//用curl获取网页源码\r\nfunction curl_get_contents($url, $referer) {\r\n$curl = curl_init($url);\r\ncurl_setopt($curl, CURLOPT_HEADER, 1);\r\ncurl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);\r\ncurl_setopt($curl, CURLOPT_REFERER, $referer);\r\ncurl_setopt($curl, CURLOPT_USERAGENT, \"Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; en-us)\");\r\ncurl_setopt($curl, CURLOPT_TIMEOUT, 10);\r\n$src = curl_exec($curl);\r\ncurl_close($curl);\r\nreturn $src;\r\n}\r\n?>\r\n[/code]
\r\n

[download id=\"2\"]

\r\n

步骤

\r\n

(1)打开记事本将上面的代码复制到记事本然后“另存为download.php”。

\r\n

(2)然后将“download.php”上传到网站跟目录。

\r\n

使用方法

\r\n

下面我以微云网盘一个分享链接做一个教程,如果没有分享链接或分享链接失效,我提供的微云网盘外直链永久下载地址则失效。

\r\n

微云分享地址:

\r\n

http://share.weiyun.com/6520c09c17d5ecefb53e7a516e4573e6

\r\n

微云网盘外直链永久下载地址:

\r\n

注:网站域名+download.php+微云分享码+.;最后加上一个“点”,最后在游览器中输入微云网盘外直链永久下载地址就会弹出下载窗口。

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4435, '20131209093422', '20131209093422', '2013-12-09 01:33:56', '2019-03-25 21:29:22', '永远把时间花在刀刃上。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4437, 'switch-simple-php-symmetric-encryption-and-decryption-methods', '简单PHP对称加密解密方法', '2013-12-09 02:37:37', '2019-03-25 21:29:22', '

[copy]http://www.thinkphp.cn/code/282.html[/copy]

\r\n
[code lang=\"php\"]\r\n/**\r\n * 通用加密\r\n * @param String $string 需要加密的字串\r\n * @param String $skey 加密EKY\r\n * @author Anyon Zou\r\n * @date 2013-08-13 19:30\r\n * @return String\r\n */\r\nfunction enCode($string = \'\', $skey = \'echounion\') {\r\n    $skey = array_reverse(str_split($skey));\r\n    $strArr = str_split(base64_encode($string));\r\n    $strCount = count($strArr);\r\n    foreach ($skey as $key => $value) {\r\n        $key < $strCount && $strArr[$key].=$value;\r\n    }\r\n    return str_replace(\'=\', \'O0O0O\', join(\'\', $strArr));\r\n}\r\n\r\n/**\r\n * 通用解密\r\n * @param String $string 需要解密的字串\r\n * @param String $skey 解密KEY\r\n * @return String\r\n * @author Anyon Zou \r\n * @date 2013-08-13 19:30\r\n */\r\nfunction deCode($string = \'\', $skey = \'echounion\') {\r\n    $skey = array_reverse(str_split($skey));\r\n    $strArr = str_split(str_replace(\'O0O0O\', \'=\', $string), 2);\r\n    $strCount = count($strArr);\r\n    foreach ($skey as $key => $value) {\r\n        $key < $strCount && $strArr[$key] = $strArr[$key][0];\r\n    }\r\n    return base64_decode(join(\'\', $strArr));\r\n}[/code]
\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4448, '20131211105210', '20131211105210', '2013-12-11 02:51:43', '2019-03-25 21:29:22', '始终保持平和的心态。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4451, '20131211162635', '20131211162635', '2013-12-11 08:26:08', '2019-03-25 21:29:22', '永远不要把希望寄托在明天。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4452, '20131212121407', '20131212121407', '2013-12-12 04:13:40', '2019-03-25 21:29:22', '在c#中,一个类只能有一个父类,但可以实现多个接口。接口的声明不能有pubic访问修饰符。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4471, '20131213183400', '20131215033026', '2013-12-13 10:34:40', '2019-03-25 21:29:22', '[\r\nbegin{vmatrix} 1 & 1& 1& 1\\ a_1& a_2& cdots &a_n \\ cdots&cdots &cdots &cdots \\ {a_1}^{n-1}& {a_2}^{n-1} & cdots & {a_n}^{n-1} end{vmatrix}= prod _{1leqslant i<jleqslant n}(a_i-a_j)\r\n]\r\n范德蒙德行列式\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4495, '20131214004831', '20131215032452', '2013-12-13 16:48:05', '2019-03-25 21:29:22', 'c#中,ArrayList的AddRange()方法可以直接添加一个数组到集合中。\r\n\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4528, '20131215045115', '20131215045115', '2013-12-14 20:50:46', '2019-03-25 21:29:22', '争取3天数学3天专业课2天政治2天英语。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4529, '20131215125646', '20131218192236', '2012-12-15 04:56:19', '2019-03-25 21:29:22', '[r(A)=0Leftrightarrow A=0]\r\n[r(A)geqslant1Leftrightarrow Aneq0] [r(A)geqslant2Leftrightarrow A至少有两行不成比例。]\r\n矩阵的秩本质上是方程组中约束条件的个数。\r\n矩阵可逆,非奇异,满秩等价。\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4537, '20131215155859', '20131215155859', '2012-12-15 07:58:30', '2019-03-25 21:29:22', '真正心无旁骛。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4589, '20131218004825', '20131218192109', '2012-12-17 16:47:55', '2019-03-25 21:29:22', '[alpha^Talpha=|alpha|^2]\r\n矩阵左转右不转是个数,左不转右转是个矩阵。\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4601, '20131218090805', '20131218090805', '2013-12-18 01:07:34', '2019-03-25 21:29:22', '日记页面终于搞定了,用的php加上smarty模版引擎制作的。\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4614, 'php-forced-output-an-error-message', 'PHP强制输出错误信息', '2013-12-19 13:23:29', '2019-03-25 21:29:22', '【版权声明:本文为特维博客原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】\r\n

问题由来

\r\n由于调试需要经常需要输出PHP错误,这时只需在PHP文件头部加入一段代码即可。\r\n

解决方案

\r\n
\r\n
    \r\n
  1. error_reporting(E_ALL);
  2. \r\n
  3. ini_set(\'display_errors\', \'1\');
  4. \r\n
  5. //如果希望把错误信息保存到文件中,请取消下面的注释
  6. \r\n
  7. //将出错信息输出到一个文本文件
  8. \r\n
  9. //ini_set(\'error_log\', dirname(__FILE__) . \'/error_log.txt\');
  10. \r\n
\r\n
\r\n在代码文件头部添加上面的代码以后,php运行错误就可以显示了,这个对于程序的临时调试很有用。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4634, 'formatted-output-in-php-var-dump', 'PHP中var_dump格式化输出', '2013-12-19 15:16:00', '2019-03-25 21:29:22', '【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】\r\n

代码如下

\r\n
\r\n
\r\n
    \r\n
  1. /**
  2. \r\n
  3.  * 输出变量
  4. \r\n
  5.  *
  6. \r\n
  7.  * @param void $varVal 变量值
  8. \r\n
  9.  * @param str $varName 变量名
  10. \r\n
  11.  * @param bool $isExit 是否输出变量之后就结束程序(TRUE:是 FALSE:否)
  12. \r\n
  13.  */
  14. \r\n
  15. function dump($varVal$isExit = FALSE){
  16. \r\n
  17.     ob_start();
  18. \r\n
  19.     var_dump($varVal);
  20. \r\n
  21.     $varVal = ob_get_clean();
  22. \r\n
  23.     $varVal = preg_replace(\"/]=>n(s+)/m\"\"] => \"$varVal);
  24. \r\n
  25.     echo \'<pre>\'.$varVal.\'</pre>\';
  26. \r\n
  27.     $isExit && exit();
  28. \r\n
  29. }
  30. \r\n
\r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4638, '20131220013456', '20131220013456', '2013-12-19 17:34:26', '2019-03-25 21:29:22', '明天看看是不是preg_match的时间限制问题。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4643, '20131220220030', '20131220220030', '2013-12-20 13:59:58', '2019-03-25 21:29:22', '天气真的是越来越冷了啊!', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4646, 'winrar-x64-simplified-chinese-version-crack', 'WinRAR X64简体中文破解版', '2013-11-20 17:04:58', '2019-03-25 21:29:22', '

[copy]winrar-x64-simplified-chinese-version-crack[/copy]

\r\n

运行效果

\r\n

\"2013-12-21_011610\" 

\r\n

下载地址

\r\n

[download id=\"8\"]

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4741, 'let-firefox-browser-like-ie-shows-a-small-x-placeholder-image-when-loading-error', '让火狐浏览器Firefox像IE浏览器一样,加载图片错误时显示小X占位符,或者错误提示的方法', '2013-12-23 21:53:07', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

问题的由来

firefox最不爽的一个地方就是图片加载失败不显示占位符这让我们这些做布局的人情何以堪,不明白浏览器的开发人员为什么要这样做,而且还不能设置。 例如下面的访问页面:

\"2013-12-24_054058\"

解决办法

方法一:安装Stylish扩展

1. 搜索附加组件Stylish并安装。

2. 打开附加组件管理器,找到刚才安装的组件,点击选项->管理样式->编写新样式,然后添加以下代码。

\"2013-12-24_054652\"

3.找到插件图标,启用样式即可。

\"2013-12-24_054744\"

效果如下

\"2013-12-24_054814\"

方法二:使用userContent.css

1. 在浏览地址栏里输入about:support;

2. 打开配置文件夹;

3. 新建chrome目录(如果没有此目录的话);

4. 新建userContent.css文件(如果没有此文件的话)把下面红色字体文字复制粘贴进去;

5. 保存退出,重启浏览器。

[code lang="css" ]/*未载入图片显示断裂标志*/\r\n@-moz-document url-prefix(http), url-prefix(file) {\r\n    img:-moz-broken{\r\n        -moz-force-broken-image-icon:1;\r\n        width:24px;\r\n        height:24px;\r\n    }\r\n}\r\n[/code]
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4760, '20131225213134', '20131225213525', '2013-12-25 13:31:03', '2019-03-25 21:29:22', '有了流量,赚钱是水到渠成的事。不要担心,面包会有的,一切都会有的。\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4770, '20131226215329', '20131226215329', '2013-12-26 13:52:57', '2019-03-25 21:29:22', '永远只做当前对自己最重要的事。时间有限,与其犹豫,不如行动。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4814, '20131228022526', '20131228222652', '2013-12-27 18:24:53', '2019-03-25 21:29:22', '矩阵乘法秩不升高。\r\n如果相乘的矩阵不是零矩阵,则矩阵的秩不变。\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4816, '20131229024621', '20131229024621', '2013-12-28 18:45:48', '2019-03-25 21:29:22', '相关与无关针对齐次线性方程组,能不能表示针对非齐次线性方程组。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4817, '20131229203158', '20131229203158', '2013-12-29 12:31:25', '2019-03-25 21:29:22', '线性无关,通俗的说就是没有多余的,相关,就是有多余的。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4824, '20131230030605', '20131230030605', '2013-12-29 19:05:31', '2019-03-25 21:29:22', '齐次的线性组合在加上非齐次的一个解为非齐次的解。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4825, '20131230031801', '20131230031854', '2013-12-29 19:17:28', '2019-03-25 21:29:22', '求通解化简步骤:归一,排他。\r\n每一行为一个方程。\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4827, '20131230032756', '20131230032756', '2013-12-29 19:27:22', '2019-03-25 21:29:22', '添加个数提高相关性,添加维数提高无关性。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4828, '20131231163524', '20131231163524', '2013-12-31 08:34:50', '2019-03-25 21:29:22', '一个人在一段时间只能专注于做一件事。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4865, '20140103025845', '20140103025845', '2014-01-02 18:58:09', '2019-03-25 21:29:22', '站点已被墙,真悲催!', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4866, '20140103030217', '20140103030350', '2014-01-02 19:01:43', '2019-03-25 21:29:22', '站点已被墙,真悲催!\r\n看来盗版电影站已死,现在这个已经没有前途了。只是还有些不甘心,哎,浪费了我那么多精力。。。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4867, '20140103030316', '20140103030512', '2014-01-02 19:02:41', '2019-03-25 21:29:22', '关键的一天,放松心情。天空没有痕迹,但我已飞过。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4870, '20140103033547', '20140103033547', '2014-01-02 19:35:12', '2019-03-25 21:29:22', '避免遗忘的最好方法就是把它记录下来。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4871, 'two-skaters', '两个滑冰运动员,体重都是60kg ,他们以6.5m/s 的速率垂直地冲向一根10m 长细杆 的两端,并同时抓住它, 如本题图所示。 若将每个运动员看成一个质点,细杆的质量可以忽略不计。', '2014-01-02 19:39:56', '2019-03-25 21:29:22', '

[copy]two-skaters[/copy]

【题目】

两个滑冰运动员,体重都是60kg,他们以6.5m/s的速率垂直地冲向一根10m长细杆的两端,并同时抓住它。若将每个运动员看成一个质点,细杆的质量可以忽略不计。

(1)求他们抓住细杆前后对于其中点的角动量;

(2)他们每人都用力往自己一边收细杆,当他们之间距离为5.0m时,各自的速率是多少?

(3)求此系杆中的张力;

(4)计算每个运动员在减少他们之间距离的过程中所作的功,并证明这功恰好等于他们动能的变化。

【新价值网解析】

解:两人和杆组成的系统角动量守恒,质心在杆的中点。

(1)各运动员在抓住杆前后,杆中点的角动量不变,均为:

[J=|vec{r}mvec{v}|=rmv=5.0times 65times 60kgcdot m^2/s=1950(kgcdot m^2/s)]

(2)在运动员往回收杆的过程中,角动量守恒

[2J=2J,即J=J\'\\ rmv=r\'mv\'=frac{r}{2}mv\'=>v\'=2v=13m/s]

(3)此时绳中的张力:

[T=frac{mv\'^2}{r\'^2}=frac{60times 13^2}{5.0/2}N=4056N]

(4)每位运动员动能的变化:

[Delta E=frac{1}{2}m(v\'^2-v^2)=frac{1}{2}times 60times (13^2-6.5^2)J=38025J]

【原创答案,禁止转载;如有疑问,尽情留言。】

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4885, 'known-as-the-earths-mass', '已知地球质量为M,半径为R.一质量为m的火箭从地面上升到距地面高度为2R处.在此过程中,地球引 力对火箭作的功为___________或__________.', '2014-01-02 20:24:05', '2019-03-25 21:29:22', '

[copy]known-as-the-earths-mass[/copy]

【题目】

已知地球质量为M,半径为R.一质量为m的火箭从地面上升到距地面高度为0.5R处.在此过程中,地球引力对火箭作的功为___________.

【新价值网解析】

[dW=-Fcdot dr=-frac{GMm}{r^2}cdot dr\\ =>W=-int_{r_1}^{r_2}frac{GMm}{r^2}cdot dr=-{GMm}(frac{1}{r_1}-frac{1}{r_2})\\ =>W=-GMm(R-1/1.5R)=-frac{GMm}{3R}]

【原创答案,禁止转载;如有疑问,欢迎留言。】

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4889, '20140104180931', '20140104180931', '2014-01-04 10:08:55', '2019-03-25 21:29:22', '从容,淡定。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4890, '20140105002231', '20140105002231', '2014-01-04 16:21:57', '2019-03-25 21:29:22', '手捂着胸脯睡觉,竟然做了一个噩梦,太吓人了。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4891, '20140105125330', '20140105125330', '2014-01-05 04:52:55', '2019-03-25 21:29:22', '从今天开始,不再更新网站,吸取教训,切勿沉溺,把时间用在最需要的事情上。不考上研究生,决不打开网站。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4892, '20140105130720', '20140105130720', '2014-01-05 05:06:44', '2019-03-25 21:29:22', '毕业设计 找.net工作 复习2015考研', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4893, '20140105180407', '20140105180407', '2014-01-05 10:03:32', '2019-03-25 21:29:22', '一切都很平静,只是有些怅然若失。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4894, '20140107133148', '20140107134046', '2014-01-07 05:31:11', '2019-03-25 21:29:22', '[IEEE754\r\n的32位\\ N=(-1)^S(1.M)2^{E-127}\\\r\n 64位\\ N=(-1)^S(1.M)2^{E-1023}\r\n\r\n]\r\n规格化表示\r\n\r\n\r\n\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4913, '20140112172354', '20140112172354', '2014-01-12 09:23:18', '2019-03-25 21:29:22', '宿舍就只剩下我一个人了啊。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4914, '20140114185644', '20140114185644', '2014-01-14 10:56:04', '2019-03-25 21:29:22', '马上就到家了。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4915, '20140117185449', '20140117185449', '2014-01-17 10:54:07', '2019-03-25 21:29:22', '终于来电了。
没电真无聊!', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4916, 'the-20140413193513', '20140413193513', '2014-01-19 01:54:22', '2019-03-25 21:29:22', '要开始做正事了。
不能再玩了。\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4919, 'the-use-of-litjson-perfect-combination-of-json-and-net', 'LitJSON的用法:json 和.net 的完美组合', '2014-01-22 03:33:04', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

\r\n

一个简单示例

\r\n
\r\n
 
\r\n
    \r\n
  1. String str = \"{\'name\':\'cyf\',\'id\':10,\'items\':[{\'itemid\':1001,\'itemname\':\'hello\'},{\'itemid\':1002,\'itemname\':\'hello2\'}]}\";                
  2. \r\n
  3. //*** 读取JSON字符串中的数据 *******************************              
  4. \r\n
  5.  JsonData jd = JsonMapper.ToObject(str);             
  6. \r\n
  7.  String name = (String)jd[\"name\"];     
  8. \r\n
  9.  long id = (long)jd[\"id\"];               
  10. \r\n
  11. JsonData jdItems = jd[\"items\"];         
  12. \r\n
  13. int itemCnt = jdItems.Count;   
  14. \r\n
  15. // 数组 items 中项的数量   
  16. \r\n
  17. foreach (JsonData item in jdItems)  
  18. \r\n
  19.  // 遍历数组 items               
  20. \r\n
  21. {int itemID = (int)item[\"itemid\"];                  
  22. \r\n
  23.  String itemName = (String)item[\"itemname\"];           
  24. \r\n
  25. }                
  26. \r\n
  27.    
  28. \r\n
  29. //*** 将JsonData转换为JSON字符串 ***************************             
  30. \r\n
  31.    
  32. \r\n
  33. String str2 = jd.ToJson();  
  34. \r\n
\r\n

下载地址

\r\n

[download id=\"11\"]

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4924, 'the-20140409103204', '20140409103204', '2014-01-25 09:51:56', '2019-03-25 21:29:22', '开始新的征程。。。\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4925, '20140125182141', '20140125182141', '2014-01-25 10:21:44', '2019-03-25 21:29:22', '唯一不能放弃的就是学习,技术上的,生活上的,社交上的。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4926, 'the-20140409103113', '20140409103113', '2014-01-26 02:51:05', '2019-03-25 21:29:22', '好长时间没来 上厕所碰着头了\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4927, '20140127141735', '20140127141735', '2014-01-27 06:17:40', '2019-03-25 21:29:22', '回老家了', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4928, 'my-interview-memoir-001', '我的面试回忆录001', '2014-01-31 03:59:54', '2019-06-11 01:29:01', '【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】\r\n\r\n面世了不少企业了,记录下我的面试经历,作为以后的参考,也希望对大家有所帮助。\r\n

第一家:XX科技

\r\nQ1:简要介绍一下你自己?\r\n\r\nQ2:说说你的性格?\r\n\r\nQ3:假如你和同事因为技术问题产生分歧,你会怎么做?\r\n\r\nQ4:你写了精通JQuery,知道JS闭包是怎么回事吗?\r\n\r\nQ5:使用过什么开源框架?说说Jquery Ajax的原理?使用JQuery开发过自己的插件吗?\r\n\r\nQ6:知道什么是json吗?怎么解析json?\r\n\r\nQ7:css熟练吗?\r\n\r\nQ8:你使用过Github,说说他是做什么的?代码托管是免费的还是收费的?\r\n\r\nQ9:说说什么是Web Service,为什么要使用它?\r\n\r\nQ10:你的薪资要求是?\r\n\r\nQ11:说说你对公司有什么问题?\r\n\r\nME:公司的主流技术是什么?\r\n\r\nHR:公司主要从事.NET开发。\r\n\r\nME:公司双休吗?\r\n\r\nHR:双休。\r\n\r\nHR:好了,你的情况我基本了解了,明天等电话。\r\n\r\n \r\n

第二家:XX科技

\r\nQ1:来段简短的自我介绍?\r\n\r\nQ2:说说C#中int类型和string类型的区别?\r\n\r\nQ4:知道什么是泛型吗?使用过吗?为什么要使用泛型?\r\n\r\nQ5:你知道object类吗?既然所有的类都继承自object,为什么还要使用泛型?\r\n\r\nQ6:说说枚举类型的作用?为什么要使用枚举?能不能用数组来替代?\r\n\r\nQ7:什么是装箱拆箱?\r\n\r\nQ8:说说SQL Server中,datetime和smalldatetime的区别?\r\n\r\nQ9:写出SQL语句,要求:查找出从2014年1月1日截至到目前为止注册的用户的姓名。\r\n\r\nQ10:知道什么是事务吗?\r\n\r\nQ11:现在有一个需求,你知道我们是做医疗软件的,需要存储病人的情况,加入每个病人有多个生理系统,比如循环系统、泌尿系统等等,对于循环系统又有心脏等等,心脏又分为左心室、右心室。现在请你设计一个数据表,要求存储病人的信息。(拿出一张纸递给我),请在纸上画出你设计的数据表。\r\n\r\nQ12:我们公司经常要处理医疗图像,所以资源的分配和释放很重要。\r\n\r\n在C++中,程序员可以手动分配和撤销资源,但是在C#中有自动垃圾回收机制,但是这种性能往往不高。你打算怎么解决?你知道在C#中怎么处理资源分配吗?\r\n\r\nQ13:什么是链表?栈和队列有什么区别?\r\n\r\nQ14:你有什么问题要问?\r\n\r\nQ15:你希望的薪资是?\r\n\r\nQ16:谢谢您的面试,明天等电话。\r\n\r\n \r\n

第三家:XX信息技术有限公司

\r\nQ1:自我介绍一下?\r\n\r\nQ2:解释一下你简历中的技术控?\r\n\r\nQ3:熟悉Linux吗?\r\n\r\nQ4:怎样提高网页的访问速度和性能?\r\n\r\nQ5:了解SEO吗?\r\n\r\nQ6:怎么解决网页越来越大的性能瓶颈?怎么处理图片?\r\n\r\nQ7:说谁从访问网页到发生404这一详细流程。http的Header中存储的是什么?\r\n\r\nQ8:表单提交的两种方式是什么?get请求的最大字节数限制是多少?\r\n\r\nQ9:了解CDN吗?\r\n\r\nQ10:怎么做负载均衡?\r\n\r\nQ11:怎么处理缓存?\r\n\r\nQ12:怎么提高数据库的查询速度?\r\n\r\nQ13:说说SQL语句的执行流程?\r\n\r\nQ14:说说你用过的框架?什么是MVC?\r\n\r\nQ15:你的薪资要求是?\r\n\r\nQ16:你最公司的期望?\r\n\r\nQ17:好了,明天等电话。\r\n\r\n \r\n

下面是我自己预测的可能会问到的问题

\r\nQ1:C#包含哪些数据类型?各自有什么特点?取值范围是什么?他们有什么区别?\r\n\r\nA:C#中的数据类型总结', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4930, 'common-settings-visual-studio', 'Visual Studio的常用设置', '2014-01-31 04:01:11', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

1.自动换行

【编辑】->【高级】->【自动换行】

2.代码小圆点

【编辑】->【高级】->【查看空白】

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4934, 'the-20140409102657', '20140409103050', '2014-02-02 07:37:48', '2019-03-25 21:29:22', '在上龛。\r\n\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4935, 'the-20140206195802', '20140206195802', '2013-02-06 11:58:03', '2019-03-25 21:29:22', '

下雪了。

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4949, 'data-types-in-csharp', 'C#中的数据类型总结', '2014-02-14 05:36:55', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

C# 类型体系包含下列几种类别:值类型、引用类型、指针类型。

[noway]【小唐提示】

Q:什么是值类型?

A:C#中的值类型详解

[/noway]

值类型的变量存储数据,而引用类型的变量存储对实际数据的引用。 引用类型也称为对象。 指针类型仅可用于 unsafe模式

[noway]【小唐提示】

Q:什么是unsafe模式?

A:C#中的unsafe详解

[/noway]

通过装箱和取消装箱,可以将值类型转换为引用类型,然后再转换回值类型。 除了装箱值类型外,无法将引用类型转换为值类型。

[noway]【小唐提示】

Q:什么是装箱拆箱?

A:C#中的装箱拆箱详解

[/noway]

本节还介绍 void 类型。

值类型也可以为 null,这意味着它们能存储其他非值状态。 有关更多信息,请参见 可以为 null 的类型。

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4954, 'in-the-csharp-unsafe', 'C#中的unsafe详解', '2014-02-14 06:12:39', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

unsafe 关键字表示不安全上下文,该上下文是任何涉及指针的操作所必需的。

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4966, 'csharp-in-the-boxing', 'C#中的装箱拆箱详解', '2014-02-14 06:38:36', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4969, 'the-csharp-value-type', 'C#中的值类型详解', '2014-02-14 06:44:02', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

值类型主要由两类组成:结构、枚举。

', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4978, 'asp-net-upload-using-swfupload-files', 'ASP .NET利用swfupload上传文件', '2014-09-20 08:52:51', '2019-03-25 21:29:22', '待续', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (4990, 'asp-net-traversal-of-repeater-inside-the-checkbox-control-and-get-the-selected-id', 'Asp .Net遍历Repeater里面的Checkbox控件并获取选中id的方法', '2014-03-12 10:23:48', '2019-03-25 21:29:22', '

【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

\r\n

有时候,我们在项目需求中总会遇到获取Repeater中id集合的时候,在此记录一下。 

\r\n

代码如下

\r\n
\r\n
 
\r\n
    \r\n
  1. /// <summary>  
  2. \r\n
  3. /// 收集Repeater中CheckBox控件中选中项目的id(注意id保存在CheckBox的ToolTip属性中)  
  4. \r\n
  5. /// </summary>  
  6. \r\n
  7. /// <param name=\"rpt\"></param>  
  8. \r\n
  9. /// <param name=\"chkId\"></param>  
  10. \r\n
  11. /// <returns></returns>  
  12. \r\n
  13. private string CollectIdsInRepeater(Repeater rpt, string chkId)  
  14. \r\n
  15. {  
  16. \r\n
  17.     string ids = \"\";  
  18. \r\n
  19.     for (int i = 0; i < rpt.Items.Count; i++)  
  20. \r\n
  21.     {  
  22. \r\n
  23.         //找到相应的Checkbox控件  
  24. \r\n
  25.         CheckBox cb = (CheckBox) rpt.Items[i].FindControl(chkId);  
  26. \r\n
  27.         //获取id并连接成字符串,用,分隔  
  28. \r\n
  29.         if (cb != null)  
  30. \r\n
  31.         {  
  32. \r\n
  33.             string selectedId = cb.ToolTip;  
  34. \r\n
  35.             if (cb.Checked)  
  36. \r\n
  37.             {  
  38. \r\n
  39.                 ids += selectedId + \",\";  
  40. \r\n
  41.             }  
  42. \r\n
  43.         }  
  44. \r\n
  45.     }  
  46. \r\n
  47.     //处理末尾的,  
  48. \r\n
  49.     if (ids.Contains(\",\"))  
  50. \r\n
  51.     {  
  52. \r\n
  53.         ids = ids.Substring(0, ids.Length - 1);  
  54. \r\n
  55.     }  
  56. \r\n
  57.     return ids;  
  58. \r\n
  59. }  
  60. \r\n
\r\n

注意事项

\r\n

注意:Repeater代码必须如下格式:

\r\n
\r\n
 
\r\n
    \r\n
  1. <asp:Repeater ID=\"rpt_word1\" runat=\"server\"> 
  2. \r\n
  3.             <ItemTemplate> 
  4. \r\n
  5.                 <asp:CheckBox ID=\"chk_word1\"  ToolTip=\'<%#Eval(\"id\") %>\'  runat=\"server\" />  <%#Eval(\"sub_name\") %> 
  6. \r\n
  7.             </ItemTemplate> 
  8. \r\n
  9.             <FooterTemplate> 
  10. \r\n
  11.                 <div class=\"noRecoredFoot\"> <%#(this.rpt_word1.Items.Count == 0) ? \"暂无记录。\" : \"\" %></div>     
  12. \r\n
  13.             </FooterTemplate> 
  14. \r\n
  15.         </asp:Repeater> 
  16. \r\n
', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5016, 'to-solve-the-powerdesigner-16-generate-datebase-for-sql20052008-object-name-sysproperties-is-invalid-problem', '解决PowerDesigner 16 Generate Datebase For Sql2005/2008 对象名sysproperties无效的问题', '2014-04-08 07:25:02', '2019-03-25 21:29:22', '

版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

问题描述

在PowerDesigner 16 中生成的sql语句,在执行的时候报错:对象名sysproperties 无效的错误。

原因分析

造成此问题的原因是由于Sql 2005、2008 删除了系统表 sysproperties 而改用 sys.extended_properties 表所致 。

解决方案

以下是通过创建sysproperties视图,以及修改powerdesigner sql语句生成模板后,再生成数据库SQL脚本执行,共分为三部:

第一步

在Sql 2005/2008 Exec the Sql 创建View \'sysproperties\',代码如下:

  1. if exists (select 1 from sysobjects where name = \'sysproperties\'and xtype = \'V\')  
  2. begin 
  3.     DROP VIEW sysproperties  
  4. end 
  5.     GO  
  6.     CREATE VIEW sysproperties  
  7.     AS 
  8.     SELECT A.name As TableName,  
  9.     A.id As TableID,B.Name As ColName,B.colid As ColID,  
  10.     B.xtype As ColType,C.name As PropName,C.Value As PropValue  
  11.     FROM sysobjects As A INNER JOIN syscolumns As B ON A.id = B.id  
  12.     INNER JOIN sys.extended_properties As C ON C.major_id = A.id   
  13.     AND ( minor_id = B.colid) 

第二步

    修改Table TableComment模板 路径是 Database -> Edit Current DBMS 窗体 General 选项卡 下 Script -> Objects -> Table -> TableComment,代码如下:

    1. [if exists (select 1   
    2. from sys.extended_properties   
    3. where major_id = object_id(\'[%QUALIFIER%]%TABLE%\')   
    4. and minor_id = 0 and name = \'MS_Description\')   
    5. begin   
    6. [%OWNER%?[.O:[execute ][exec ]]sp_dropextendedproperty [%R%?[N]]\'MS_Description\',   
    7. [%R%?[N]]\'user\', [%R%?[N]]%.q:OWNER%, [%R%?[N]]\'table\', [%R%?[N]]%.q:TABLE%   
    8. :declare @CurrentUser sysname   
    9. select @CurrentUser = user_name()   
    10. [.O:[execute ][exec ]]sp_dropextendedproperty [%R%?[N]]\'MS_Description\',   
    11. [%R%?[N]]\'user\', [%R%?[N]]@CurrentUser, [%R%?[N]]\'table\', [%R%?[N]]%.q:TABLE%   
    12. ]   
    13. end   
    14.  
    15. ][%OWNER%?[.O:[execute ][exec ]]sp_addextendedproperty [%R%?[N]]\'MS_Description\',   
    16. [%R%?[N]]%.q:COMMENT%,   
    17. [%R%?[N]]\'user\', [%R%?[N]]%.q:OWNER%, [%R%?[N]]\'table\', [%R%?[N]]%.q:TABLE%   
    18. :select @CurrentUser = user_name()   
    19. [.O:[execute ][exec ]]sp_addextendedproperty [%R%?[N]]\'MS_Description\',   
    20. [%R%?[N]]%.q:COMMENT%,   
    21. [%R%?[N]]\'user\', [%R%?[N]]@CurrentUser, [%R%?[N]]\'table\', [%R%?[N]]%.q:TABLE%   

    第三步

    修改Column ColumnComment模板 路径是 Database -> Edit Current DBMS 窗体 General 选项卡 下 Script -> Objects -> Column -> ColumnComment,代码如下:

    1. [if exists (select 1  
    2. from sysproperties  
    3. where TableID = object_id(\'[%QUALIFIER%]%TABLE%\')  
    4. and ColName = %.q:COLUMN% AND PropName=\'MS_Description\')  
    5. begin 
    6. [%OWNER%?[.O:[execute ][exec ]]sp_dropextendedproperty [%R%?[N]]\'MS_Description\',  
    7. [%R%?[N]]\'user\', [%R%?[N]]%.q:OWNER%, [%R%?[N]]\'table\', [%R%?[N]]%.q:TABLE%, [%R%?[N]]\'column\', [%R%?[N]]%.q:COLUMN%  
    8. :declare @CurrentUser sysname  
    9. select @CurrentUser = user_name()  
    10. [.O:[execute ][exec ]]sp_dropextendedproperty [%R%?[N]]\'MS_Description\',   
    11. [%R%?[N]]\'user\', [%R%?[N]]@CurrentUser, [%R%?[N]]\'table\', [%R%?[N]]%.q:TABLE%, [%R%?[N]]\'column\', [%R%?[N]]%.q:COLUMN%  
    12. ]  
    13.  
    14. end 
    15.  
    16. ][%OWNER%?[.O:[execute ][exec ]]sp_addextendedproperty [%R%?[N]]\'MS_Description\',  
    17. [%R%?[N]]%.q:COMMENT%,  
    18. [%R%?[N]]\'user\', [%R%?[N]]%.q:OWNER%, [%R%?[N]]\'table\', [%R%?[N]]%.q:TABLE%, [%R%?[N]]\'column\', [%R%?[N]]%.q:COLUMN%  
    19. :select @CurrentUser = user_name()  
    20. [.O:[execute ][exec ]]sp_addextendedproperty [%R%?[N]]\'MS_Description\',   
    21. [%R%?[N]]%.q:COMMENT%,  
    22. [%R%?[N]]\'user\', [%R%?[N]]@CurrentUser, [%R%?[N]]\'table\', [%R%?[N]]%.q:TABLE%, [%R%?[N]]\'column\', [%R%?[N]]%.q:COLUMN%  

    使用Generate Database 生成的SQL便可在SQL 2005/2008下执行 不在报找不到sysproperties 的错误。

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5031, 'the-20140409103003', '20140409103003', '2014-04-09 02:28:01', '2019-03-25 21:29:22', 'intellij idea开发安卓真不错哈', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5035, 'the-20140409112934', '20140409112934', '2014-04-09 03:27:31', '2019-03-25 21:29:22', '开始整理代码仓库。。。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5036, 'ordpress-how-to-exclude-specific-classification-of-articles', 'wordpress如何排除首页特定分类文章', '2014-04-09 03:57:08', '2019-03-25 21:29:22', '
    情景重现\r\n========\r\n有时候,处于某种原因,我们不想让某些文章在首页显示,但是wordpress默认是显示所有文章的。\r\n方法如下\r\n========\r\n在```主题的functions.php```或者```插件```的合适位置加入以下代码即可:\r\n```php\r\n//过滤首页分类文章\r\nfunction exclude_category_home($query) {\r\n	if ($query->is_home ) {\r\n		$query->set(\'cat\',\'-14,-99,-69,-70,-87,-99\');\r\n	}\r\n	return $query;\r\n}\r\nadd_filter(\'pre_get_posts\',\'exclude_category_home\');\r\n```\r\n个人建议最好写在插件里面,避免更换主题对文章的影响。     
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5040, 'to-solve-the-problem-of-header-plus-utf8-in-php', 'php中header加上utf8乱码解决问题', '2014-04-09 06:43:40', '2019-03-25 21:29:22', '

    【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

    加上以下代码:

    1. header("Content-type: text/html; charset=utf-8");  

    具体生成后的代码:

    1. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5046, 'the-20140410004249', '20140410004249', '2014-04-09 16:40:46', '2019-03-25 21:29:22', '明天开始招聘网站的开发。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5047, 'the-20140410004415', '20140410004415', '2014-04-09 16:42:13', '2019-03-25 21:29:22', '白天设计数据库,晚上毕业设计。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5050, 'csharp-use-httpwebrequest-to-send-post-and-get-requests-to-achieve-simulated-landing', 'C#利用HttpWebRequest发送post和get请求实现模拟登陆', '2014-04-11 03:29:02', '2019-03-25 21:29:22', '

    【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

    代码如下
    1. using System;  
    2. using System.Collections;  
    3. using System.Collections.Generic;  
    4. using System.IO;  
    5. using System.Net;  
    6. using System.Text;  
    7. using System.Threading;  
    8.  
    9. namespace simulate_login  
    10. {  
    11.     public class HttpHelper  
    12.     {  
    13.         #region 获取CooKie  
    14.  
    15.         /// <summary>  
    16.         /// 传递header获取CooKie  
    17.         /// </summary>  
    18.         /// <param name="loginUrl"></param>  
    19.         /// <param name="postdata"></param>  
    20.         /// <param name="header"></param>  
    21.         /// <returns></returns>  
    22.         public static CookieContainer GetCooKie(string loginUrl, string postdata, HttpHeader header)  
    23.         {  
    24.             HttpWebRequest request = null;  
    25.             HttpWebResponse response = null;  
    26.             try 
    27.             {  
    28.                 CookieContainer cc = new CookieContainer();  
    29.                 request = (HttpWebRequest) WebRequest.Create(loginUrl);  
    30.                 request.Method = header.method;  
    31.                 request.ContentType = header.contentType;  
    32.                 byte[] postdatabyte = Encoding.UTF8.GetBytes(postdata);  
    33.                 request.ContentLength = postdatabyte.Length;  
    34.                 request.AllowAutoRedirect = false;  
    35.                 request.CookieContainer = cc;  
    36.                 request.KeepAlive = true;  
    37.  
    38.                 //提交请求  
    39.                 Stream stream;  
    40.                 stream = request.GetRequestStream();  
    41.                 stream.Write(postdatabyte, 0, postdatabyte.Length);  
    42.                 stream.Close();  
    43.  
    44.                 //接收响应  
    45.                 response = (HttpWebResponse) request.GetResponse();  
    46.                 response.Cookies = request.CookieContainer.GetCookies(request.RequestUri);  
    47.  
    48.                 CookieCollection cook = response.Cookies;  
    49.                 //Cookie字符串格式  
    50.                 string strcrook = request.CookieContainer.GetCookieHeader(request.RequestUri);  
    51.  
    52.                 return cc;  
    53.             }  
    54.             catch (Exception ex)  
    55.             {  
    56.                 throw ex;  
    57.             }  
    58.         }  
    59.  
    60.         #endregion  
    61.  
    62.         #region 传递cookie和header获取html  
    63.  
    64.         /// <summary>  
    65.         /// 获取html  
    66.         /// </summary>  
    67.         /// <param name="getUrl"></param>  
    68.         /// <param name="cookieContainer"></param>  
    69.         /// <param name="header"></param>  
    70.         /// <returns></returns>  
    71.         public static string GetHtml(string getUrl, CookieContainer cookieContainer, HttpHeader header)  
    72.         {  
    73.             Thread.Sleep(1000);  
    74.             HttpWebRequest httpWebRequest = null;  
    75.             HttpWebResponse httpWebResponse = null;  
    76.             try 
    77.             {  
    78.                 httpWebRequest = (HttpWebRequest) HttpWebRequest.Create(getUrl);  
    79.                 httpWebRequest.CookieContainer = cookieContainer;  
    80.                 httpWebRequest.ContentType = header.contentType;  
    81.                 httpWebRequest.ServicePoint.ConnectionLimit = header.maxTry;  
    82.                 httpWebRequest.Referer = getUrl;  
    83.                 httpWebRequest.Accept = header.accept;  
    84.                 httpWebRequest.UserAgent = header.userAgent;  
    85.                 httpWebRequest.Method = "GET";  
    86.                 httpWebResponse = (HttpWebResponse) httpWebRequest.GetResponse();  
    87.                 Stream responseStream = httpWebResponse.GetResponseStream();  
    88.                 StreamReader streamReader = new StreamReader(responseStream, Encoding.UTF8);  
    89.                 string html = streamReader.ReadToEnd();  
    90.                 streamReader.Close();  
    91.                 responseStream.Close();  
    92.                 httpWebRequest.Abort();  
    93.                 httpWebResponse.Close();  
    94.                 return html;  
    95.             }  
    96.             catch (Exception e)  
    97.             {  
    98.                 if (httpWebRequest != null) httpWebRequest.Abort();  
    99.                 if (httpWebResponse != null) httpWebResponse.Close();  
    100.                 return string.Empty;  
    101.             }  
    102.         }  
    103.  
    104.         #endregion  
    105.  
    106.         #region 传递cookie获取验证码  
    107.  
    108.         /// <summary>  
    109.         /// 下载验证码图片并保存到本地  
    110.         /// </summary>  
    111.         /// <param name="Url">验证码URL</param>  
    112.         /// <param name="cookCon">Cookies值</param>  
    113.         /// <param name="savePath">保存位置/文件名</param>  
    114.         public static bool DowloadCheckImg(string Url, CookieContainer cookCon, string savePath)  
    115.         {  
    116.             bool bol = true;  
    117.             HttpWebRequest webRequest = (HttpWebRequest) WebRequest.Create(Url);  
    118.             //属性配置  
    119.             webRequest.AllowWriteStreamBuffering = true;  
    120.             webRequest.Credentials = System.Net.CredentialCache.DefaultCredentials;  
    121.             webRequest.MaximumResponseHeadersLength = -1;  
    122.             webRequest.Accept =  
    123.                 "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*";  
    124.             webRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Maxthon; .NET CLR 1.1.4322)";  
    125.             webRequest.ContentType = "application/x-www-form-urlencoded";  
    126.             webRequest.Method = "GET";  
    127.             webRequest.Headers.Add("Accept-Language", "zh-cn");  
    128.             webRequest.Headers.Add("Accept-Encoding", "gzip,deflate");  
    129.             webRequest.KeepAlive = true;  
    130.             webRequest.CookieContainer = cookCon;  
    131.             try 
    132.             {  
    133.                 //获取服务器返回的资源  
    134.                 using (HttpWebResponse webResponse = (HttpWebResponse) webRequest.GetResponse())  
    135.                 {  
    136.                     using (Stream sream = webResponse.GetResponseStream())  
    137.                     {  
    138.                         List<byte> list = new List<byte>();  
    139.                         while (true)  
    140.                         {  
    141.                             int data = sream.ReadByte();  
    142. \r\n
    143.                             if (data == -1)  
    144.                                 break;  
    145.                             list.Add((byte) data);  
    146.                         }  
    147.                         File.WriteAllBytes(savePath, list.ToArray());  
    148.                     }  
    149.                 }  
    150.             }  
    151.             catch (WebException ex)  
    152.             {  
    153.                 bol = false;  
    154.             }  
    155.             catch (Exception ex)  
    156.             {  
    157.                 bol = false;  
    158.             }  
    159.             return bol;  
    160.         }  
    161.  
    162.         #endregion  
    163.  
    164.         #region 不用Cookie发送get请求  
    165.  
    166.         /// <summary>  
    167.         /// 不用Cookie发送get请求  
    168.         /// </summary>  
    169.         /// <param name="strUrl"></param>  
    170.         /// <returns></returns>  
    171.         public static string Get(string strUrl)  
    172.         {  
    173.             string strRet = null;  
    174.             try 
    175.             {  
    176.                 HttpWebRequest request = (HttpWebRequest) WebRequest.Create(strUrl);  
    177.                 request.Timeout = 2000;  
    178.                 HttpWebResponse response = (HttpWebResponse) request.GetResponse();  
    179.                 System.IO.Stream resStream = response.GetResponseStream();  
    180.                 Encoding encode = System.Text.Encoding.UTF8;  
    181.                 StreamReader readStream = new StreamReader(resStream, encode);  
    182.                 Char[] read = new Char[256];  
    183.                 int count = readStream.Read(read, 0, 256);  
    184.                 while (count > 0)  
    185.                 {  
    186.                     String str = new String(read, 0, count);  
    187.                     strRet = strRet + str;  
    188.                     count = readStream.Read(read, 0, 256);  
    189.                 }  
    190.                 resStream.\r\nClose();  
    191.             }  
    192.             catch (Exception e)  
    193.             {  
    194.                 strRet = "";  
    195.             }  
    196.             return strRet;  
    197.         }  
    198.  
    199.         #endregion  
    200.  
    201.         #region 不用Cookie发送post请求  
    202.  
    203.         /// <summary>  
    204.         /// 不用Cookie发送post请求  
    205.         /// </summary>  
    206.         /// <param name="strUrl"></param>  
    207.         /// <param name="strParm"></param>  
    208.         /// <returns></returns>  
    209.         public static string Post(string strUrl, string strParm)  
    210.         {  
    211.             Encoding encode = System.Text.Encoding.Default;  
    212.             byte[] arrB = encode.GetBytes(strParm);  
    213.             HttpWebRequest myReq = (HttpWebRequest) WebRequest.Create(strUrl);  
    214.             myReq.Method = "POST";  
    215.             myReq.ContentType = "application/x-www-form-urlencoded";  
    216.             myReq.ContentLength = arrB.Length;  
    217.             Stream outStream = myReq.GetRequestStream();  
    218.             outStream.Write(arrB, 0, arrB.Length);  
    219.             outStream.Close();  
    220.             WebResponse myResp = null;  
    221.             try 
    222.             {  
    223.                 //接收HTTP做出的响应  
    224.                 myResp = myReq.GetResponse();  
    225.             }  
    226.             catch (Exception e)  
    227.             {  
    228.                 throw e;  
    229.             }  
    230.             Stream ReceiveStream = myResp.GetResponseStream();  
    231.             StreamReader readStream = new StreamReader(ReceiveStream, encode);  
    232.             Char[] read = new Char[256];  
    233.             int count = readStream.Read(read, 0, 256);  
    234.             string str = null;  
    235.             while (count > 0)  
    236.             {  
    237.                 str += new String(read, 0, count);  
    238.                 count = readStream.Read(read, 0, 256);  
    239.             }  
    240.             readStream.Close();  
    241.             myResp.Close();  
    242.           \r\n0; return str;  
    243.         }  
    244.     }  
    245.  
    246.     #endregion  
    247.  
    248.     #region HttpHeader辅助类  
    249.  
    250.     public class HttpHeader  
    251.     {  
    252.         public string contentType { get; set; }  
    253.  
    254.         public string accept { get; set; }  
    255.  
    256.         public string userAgent { get; set; }  
    257.  
    258.         public string method { get; set; }  
    259.  
    260.         public int maxTry { get; set; }  
    261.     }  
    262.  
    263.     #endregion  

    测试数据

    1. HttpHeader header = new HttpHeader();  
    2.          header.accept =  
    3.              "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/x-silverlight, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, application/x-silverlight-2-b1, */*";  
    4.          header.contentType = "application/x-www-form-urlencoded";  
    5.          header.method = "POST";  
    6.          header.userAgent =  
    7.              "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)";  
    8.          header.maxTry = 300;  
    9.  
    10.          string parameter =  
    11.              String.Format(  
    12.                  "email={0}&password={1}&icode=&origURL=http%3A%2F%2Fwww.renren.com%2Fhome&domain=renren.com&key_id=1&_rtk=90484476",  
    13.                  "renren_username", "renren_password");  
    14.          string html = HttpHelper.GetHtml("http://guide.renren.com/guide",  
    15.              HttpHelper.GetCooKie("http://www.renren.com/PLogin.do",  
    16.                  parameter, header), header);  
    17.  
    18.          Response.Write(html); 
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5053, 'the-20140412001955', '20140412001955', '2014-04-11 16:17:43', '2019-03-25 21:29:22', '整合铁通接口,又加班了。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5054, 'the-20140413193321', '20140413193321', '2014-04-13 11:31:09', '2019-03-25 21:29:22', '铁通模拟登录终于成功了。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5056, 'the-20140418225534', '20140418225534', '2014-04-18 14:53:06', '2019-03-25 21:29:22', '开始毕业设计。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5059, 'asp-net-mvc4-study-notes-one', 'Asp .Net Mvc4学习笔记001:环境准备、下载与安装', '2014-04-22 01:43:17', '2019-03-25 21:29:22', '

    下载地址

    http://www.microsoft.com/zh-CN/download/details.aspx?id=30683

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5062, 'asp-net-mvc4-study-notes-two-install-entityframework', '原Asp .Net Mvc4学习笔记002:安装EntityFramework', '2014-04-22 03:11:08', '2019-03-25 21:29:22', '

    \"2014-04-22_111016\"

     

     

    每个程序包的所有者将相应程序包授权给您。Microsoft 不负责也不会授予对第三方程序包的任何许可。有些程序包可能包含受其他许可证控制的依赖项。请访问程序包源(源) URL 以确定所有依赖项。

    程序包管理器控制台主机版本 2.8.50126.400

    键入“get-help NuGet”以查看所有可用的 NuGet 命令。

    PM> Install-Package EntityFramework
    正在安装“EntityFramework 6.1.0”。
    您正在从 Microsoft 下载 EntityFramework,有关此程序包的许可协议在 http://go.microsoft.com/fwlink/?LinkID=320539 上提供。请检查此程序包是否有其他依赖项,这些依赖项可能带有各自的许可协议。您若使用程序包及依赖项,即构成您接受其许可协议。如果您不接受这些许可协议,请从您的设备中删除相关组件。
    已成功安装“EntityFramework 6.1.0”。
    正在将“EntityFramework 6.1.0”添加到 UCsoft.DAL。
    已成功将“EntityFramework 6.1.0”添加到 UCsoft.DAL。

    Type \'get-help EntityFramework\' to see all available Entity Framework commands.

    PM>

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5064, 'the-20140422214904', '20140422214904', '2014-04-22 13:46:23', '2019-03-25 21:29:22', '无题。。。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5065, 'the-20140424133215', '20140424133215', '2014-04-24 05:29:32', '2019-03-25 21:29:22', '最艰难的日子,往往收获更多。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5066, '5066', '20140426083044', '2014-04-26 00:27:57', '2019-03-25 21:29:22', '不管多忙 每天必须抽出1小时时间学习', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5068, 'asp-net-mvc-action-redirect-summary', 'Asp .Net Mvc4学习笔记003:Asp.net Mvc Action重定向总结', '2014-05-01 04:43:36', '2019-03-25 21:29:22', '
    #region 到要经过执行controller里方法后 显示出页面。\r\n//return RedirectToAction("Index");//可跳出本controller  \r\n//return RedirectToRoute(new {controller="Home",action="Index"});//可跳出本controller  \r\n//Response.Redirect("Index");//只能使用本controller下的方法名称。返回值为void  \r\n//return Redirect("Index");//只能使用本controller下的方法名称。  \r\n#endregion\r\n\r\n#region 直接显示出对应的页面 不经过执行controller的方法。\r\n//return View("Index");//非本方法  \r\n//return  View("~/Views/Home/Index.cshtml");//这种方法是写全路径  \r\n#endregion\r\n\r\nreturn View();  
    \r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5070, 'linq-to-entities-does-not-recognize-the-method-int32-parse-systemstring-this-method-cannot-be-converted-to-the-storage-solve', 'LINQ to Entities 不识别方法“Int32 Parse(System.String)”,因此该方法无法转换为存储表达式。解决', '2014-05-02 04:46:08', '2019-03-25 21:29:22', '

    【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

    \r\n

    问题描述

    \r\n

    最近在用LINQ to Entities,看看下面的代码

    \r\n

    //获取分页数据

    \r\n

                var admins = from aa in db.VAccountAdmins

    \r\n

                    select aa;

    \r\n

                //处理过滤规则

    \r\n

                if (null != filterRules)

    \r\n

                {

    \r\n

                    JArray roles = (JArray) JsonConvert.DeserializeObject(filterRules);

    \r\n

                    foreach (var fr in roles)

    \r\n

                    {

    \r\n

                        string field = fr[\"field\"].ToString();

    \r\n

                        string op = fr[\"op\"].ToString();

    \r\n

                        string value = fr[\"value\"].ToString();

    \r\n

                        switch (field)

    \r\n

                        {

    \r\n

                            case \"account_id\":

    \r\n

                                switch (op)

    \r\n

                                {

    \r\n

                                    case \"all\":

    \r\n

                                        break;

    \r\n

                                    case \"equal\":

    \r\n

                                        admins = admins.Where(a => a.account_id == int.Parse(value));

    \r\n

                                        break;

    \r\n

                                }

    \r\n

                                break;

    \r\n

                        }

    \r\n

                    }

    \r\n

    //处理排序

    \r\n

                PagedList<VAccountAdmin> alist = null;

    \r\n

                if (order == \"desc\")

    \r\n

                {

    \r\n

                    alist = admins.OrderByDescending(a => sort).ToPagedList(page, rows);

    \r\n

                }

    \r\n

                else

    \r\n

                {

    \r\n

                    alist = admins.OrderBy(a => sort).ToPagedList(page, rows);

    \r\n

                }

    \r\n

                //返回easy json数据

    \r\n

                var gridData = new

    \r\n

                {

    \r\n

                    total = db.VAccountAdmins.ToList().Count,

    \r\n

                    rows = alist

    \r\n

                };

    \r\n

                return Json(gridData);

    \r\n

    乍一看没问题,可是运行却抛出异常:

    \r\n

     

    \r\n

    原因分析

    \r\n

    LINQ在筛选条件中如果使用率lanbla表达式,则不能在使用ToString、Int.Palse等C#代码。深层次的原因在于lambula表达式的解析。

    \r\n

    解决方案

    \r\n

    把C#代码单独写出来,然后LINQ里面仅仅传送变量。

    \r\n

    switch (field)

    \r\n

                        {

    \r\n

                            case \"account_id\":

    \r\n

                                switch (op)

    \r\n

                                {

    \r\n

                                    case \"all\":

    \r\n

                                        break;

    \r\n

                                    case \"equal\":

    \r\n

                                        int aid = int.Parse(value);

    \r\n

                                        admins = admins.Where(a => a.account_id ==aid );

    \r\n

                                        break;

    \r\n

                                }

    \r\n

                                break;

    \r\n

                        }

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5073, 'the-20140502172357', '20140502172357', '2014-05-02 09:20:48', '2019-03-25 21:29:22', '用效率换时间。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5074, 'linq-gets-the-tree-classification-number', 'LINQ获取树形分类的层数', '2014-05-02 14:49:03', '2019-03-25 21:29:22', '

    【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

    数据库中的数据格式:

    字段 数据类型
    id int
    department_pid int
    department_name nvarchar(20)

     

    1. CREATE TABLE [dbo].[T_user_department](  
    2.     [id] [int] IDENTITY(1,1) NOT NULL,  
    3.     [department_pid] [int] NULL,  
    4.     [department_name] [nvarchar](20) NULL,  
    5.  CONSTRAINT [PK_T_USER_DEPARTMENT] PRIMARY KEY CLUSTERED   
    6. (  
    7.     [id] ASC 
    8. )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]  
    9. ) ON [PRIMARY]  
    10.  
    11. SET IDENTITY_INSERT [dbo].[T_user_department] ON 
    12. INSERT [dbo].[T_user_department] ([id], [department_pid], [department_name]) VALUES (1, 0, N\'技术部\')  
    13. INSERT [dbo].[T_user_department] ([id], [department_pid], [department_name]) VALUES (2, 0, N\' 销售部\')  
    14. INSERT [dbo].[T_user_department] ([id], [department_pid], [department_name]) VALUES (3, 2, N\'销售1部\')  
    15. INSERT [dbo].[T_user_department] ([id], [department_pid], [department_name]) VALUES (4, 2, N\'销售2部\')  
    16. INSERT [dbo].[T_user_department] ([id], [department_pid], [department_name]) VALUES (5, 0, N\'客服部\')  
    17. INSERT [dbo].[T_user_department] ([id], [department_pid], [department_name]) VALUES (6, 3, N\'人事部\')  
    18. SET IDENTITY_INSERT [dbo].[T_user_department] OFF 
    19.  
    20. ALTER TABLE [dbo].[T_user_department] ADD  DEFAULT ((0)) FOR [department_pid]  
    21.  

    树形格式(为了直观,按id排列)

    1

    2

      3

          6

      4

    5

    获取层数的测试代码:

    1. #region  
    2.         // Admin/Account/Admin/GetDepartmentData  
    3.         public string GetDepartmentData(int id)  
    4.         {  
    5.             return GetLayerById(id).ToString();  
    6.         }  
    7.  
    8.  
    9.         /// <summary>  
    10.         /// 获取分类的层数  
    11.         /// </summary>  
    12.         /// <param name="id">根据id获取树的层数</param>  
    13.         /// <returns>树的层数</returns>  
    14.         private int GetLayerById(int id)  
    15.         {  
    16.             int layer = 1;  
    17.             for (int subId =(int)db.TUserDepartments.Where(d=>d.id==id).Select(d=>d.department_pid).ToList().FirstOrDefault(); subId != 0; )  \r\n
    18.             {  
    19.                 subId = (int)db.TUserDepartments.Where(d => d.id == subId).Select(d => d.department_pid).ToList().FirstOrDefault();  
    20.                 layer++;  
    21.             }  
    22.             return layer;  
    23.         }  
    24.         #endregion 
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5076, 'easyui-combotree-data-binding-tree-classification', 'EasyUI ComboTree数据绑定树形分类显示', '2014-05-02 17:04:33', '2019-03-25 21:29:22', '

    【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

    承接上篇博文【LINQ获取树形分类的层数】。在上文中,笔者只分享了层数,在这里我把完整的实现贴出来,欢迎批评指正。

    先附上效果图:

    \"1\"

     

    \"2\"

    首先是Tree公共类

    1. public class Tree  
    2.    {  
    3.        public int ModuleID { get; set; }  
    4.  
    5.        public int ParentID { get; set; }  
    6.  
    7.        public int ModulePath { get; set; }  
    8.  
    9.        public string ModuleName { get; set; }  
    10.    }  

    接下来就是TreeHelper了,这个类是获取json数据的核心他将数据库中的数据组装成了EasyUI可以接受的json格式。

    1. public class DepartmentTreeHelper  
    2.   {  
    3.       private static ZhaopinModels db = new ZhaopinModels();  
    4.  
    5.       #region 获取父类集合  
    6.  
    7.       public static IList<Tree> returnParentTree()  
    8.       {  
    9.           IList<Tree> trees = new List<Tree>();  
    10.           List<TUserDepartment> departments = db.TUserDepartments.Where(d => d.department_pid == 0).ToList();  
    11.  
    12.           foreach (var userDepartment in departments)  
    13.           {  
    14.               Tree tree = new Tree();  
    15.               tree.ModuleID = userDepartment.id;  
    16.               tree.ParentID = (int) userDepartment.department_pid;  
    17.               tree.ModulePath = GetLayerById(tree.ModuleID);  
    18.               tree.ModuleName = userDepartment.department_name;  
    19.               trees.Add(tree);  
    20.           }  
    21.           return trees;  
    22.       }  
    23.  
    24.       #endregion  
    25.  
    26.       #region 获取分类的层数  
    27.  
    28.       /// <summary>  
    29.       /// 获取分类的层数  
    30.       /// </summary>  
    31.       /// <param name="id">根据id获取树的层数</param>  
    32.       /// <returns>树的层数</returns>  
    33.       pr\r\nivate static int GetLayerById(int id)  
    34.       {  
    35.           int layer = 1;  
    36.           for (  
    37.               int subId =  
    38.                   (int)  
    39.                       db.TUserDepartments.Where(d => d.id == id)  
    40.                           .Select(d => d.department_pid)  
    41.                           .ToList()  
    42.                           .FirstOrDefault();  
    43.               subId != 0;)  
    44.           {  
    45.               subId =  
    46.                   (int)  
    47.                       db.TUserDepartments.Where(d => d.id == subId)  
    48.                           .Select(d => d.department_pid)  
    49.                           .ToList()  
    50.                           .FirstOrDefault();  
    51.               layer++;  
    52.           }  
    53.           return layer;  
    54.       }  
    55.  
    56.       #endregion  
    57.  
    58.       #region 判断分类是否有子类  
    59.  
    60.       /// <summary>  
    61.       /// 判断分类是否有子类  
    62.       /// </summary>  
    63.       /// <param name="id"></param>  
    64.       /// <returns></returns>  
    65.       public static bool IsHaveChild(int id)  
    66.       {  
    67.           bool flag = false;  
    68.           var did = db.TUserDepartments.Where(d => d.department_pid == id).Select(d => d.id).ToList();  
    69.           if (did.Count > 0)  
    70.           {  
    71.               flag = true;  
    72.           }  
    73.           return flag;  
    74.       }  
    75.  
    76.       #endregion  
    77.  
    78.       #region 根据id获取子类  
    79.  
    80.       /// <summary>  
    81.       /// 根据id获取子类  
    82.       /// </summary>  
    83.       /// <param name="id"></param>  
    84.       /// <returns></returns>  
    85.       public static IList<Tree> GetChild(int id)  
    86.       {  
    87. \r\n0;         IList<Tree> t = new List<Tree>();  
    88.           List<TUserDepartment> departments = db.TUserDepartments.Where(d => d.department_pid == id).ToList();  
    89.           foreach (var d in departments)  
    90.           {  
    91.               Tree tParent = new Tree();  
    92.               tParent.ModuleID = d.id;  
    93.               tParent.ParentID = (int) d.department_pid;  
    94.               tParent.ModulePath = DepartmentTreeHelper.GetLayerById(tParent.ModuleID);  
    95.               tParent.ModuleName = d.department_name;  
    96.  
    97.               t.Add(tParent);  
    98.           }  
    99.           return t;  
    100.       }  
    101.  
    102.       #endregion  
    103.  
    104.       #region 获取json  
    105.  
    106.       /// <summary>  
    107.       /// 获取json  
    108.       /// </summary>  
    109.       /// <returns></returns>  
    110.       public static string GetJson()  
    111.       {  
    112.           string json = "[";  
    113.           IList<Tree> t = DepartmentTreeHelper.returnParentTree();  
    114.           foreach (Tree model in t)  
    115.           {  
    116.               if (model != t[t.Count - 1])  
    117.               {  
    118.                   json += DepartmentTreeHelper.GetJsonByModel(model) + ",";  
    119.               }  
    120.               else 
    121.               {  
    122.                   json += DepartmentTreeHelper.GetJsonByModel(model);  
    123.               }  
    124.           }  
    125.           json += "]";  
    126.           json = json.Replace("\'", """);  
    127.           return json;  
    128.       }  
    129.  
    130.       #endregion  
    131.  
    132.       #region 根据模型生成json  
    133.  
    134.       /// <summary>  
    135.       /// 根据模型生成json  
    136.       /// </summary>  
    137.       /// <param name="t"></param>  
    138.       /// <returns></returns>  
    139.       public static string GetJsonByModel(Tree t)  
    140.       {  
    141.           string json = "";  
    142.           bool flag = D\r\nepartmentTreeHelper.IsHaveChild(t.ModuleID);  
    143.  
    144.           json = "{" 
    145.                  + "\'id\':\'" + t.ModuleID + "\'," 
    146.                  + "\'text\':\'" + t.ModuleName + "\'," 
    147.                  + "\'iconCls\':\'ok\'," 
    148.                  + "\'children\':";  
    149.           if (!flag)  
    150.           {  
    151.               json += "null}";  
    152.           }  
    153.           else 
    154.           {  
    155.               json += "[";  
    156.               IList<Tree> list = DepartmentTreeHelper.GetChild(t.ModuleID);  
    157.               foreach (Tree tree in list)  
    158.               {  
    159.                   if (tree != list[list.Count - 1])  
    160.                   {  
    161.                       json += GetJsonByModel(tree) + ",";  
    162.                   }  
    163.                   else 
    164.                   {  
    165.                       json += GetJsonByModel(tree);  
    166.                   }  
    167.               }  
    168.               json += "]}";  
    169.           }  
    170.           return json;  
    171.       }  
    172.  
    173.       #endregion  
    174.   } 
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5079, 'the-20140506215325', '20140506215325', '2014-05-06 13:50:07', '2019-03-25 21:29:22', '抽空了解一下.net元数据。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5080, 'the-20140507184146', '20140507184146', '2014-05-07 10:38:23', '2019-03-25 21:29:22', '在mvc 中使用easyui时 如果前台使用combotrre且多选 后台可以自动转化成范型list', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5081, 'the-20140507231357', '20140507231357', '2014-05-07 15:10:37', '2019-03-25 21:29:22', 'mvc路由的奇怪现象 深层目录的路由必须写在上面', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5085, 'easy-ui-combobox-text-change-event-notice', 'Easy UI Combobox文本改变事件注意事项', '2014-05-10 12:23:16', '2019-03-25 21:29:22', '

    【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

    要先得到 conbobox对象,而不是jquery对象,代码如下 :

    1. $(function(){  
    2.  
    3.             $("#sel-graph-type").combobox({  
    4.                 onChange: function(value) {  
    5.                      alert(value);  
    6.                 }  
    7.             });  
    8.  
    9.         });  
    10.  
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5095, 'the-20140510221032', '20140510221032', '2014-05-10 14:07:01', '2019-03-25 21:29:22', '利用css偏移技术,可以避免多个图片的下载,提高网页加载速度。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5096, 'the-20140511082145', '20140511082145', '2014-05-11 00:18:16', '2019-03-25 21:29:22', '了解一下mock的原理。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5097, 'the-original-asp-net-mvc-client-detects-a-potentially-dangerous-request-form-value', 'Asp .Net MVC从客户端中检测到有潜在危险的 Request.Form 值', '2014-05-12 01:16:59', '2019-03-25 21:29:22', '

    在传统的.net Request验证中 ,只需要在WebConfig HttpRuntime节点 加入 RequestValidateMode 属性,值为2.0(此处2.0并非Framework版本)

    在pages 或页面中将  validateRequest设为 false 即可。

    但以上设置在MVC中失效。

    在MVC中 设置如下:

    ValidateInput

    在MVC的 方法 或控制器上 加入  [ValidateInput(false)]标识就OK了,例如:

    1. /// <summary>  
    2. /// 添加角色信息  
    3. /// </summary>  
    4. /// <param name="role_name"></param>  
    5. /// <param name="role_pid"></param>  
    6. /// <param name="permission_str"></param>  
    7. /// <param name="profession_id"></param>  
    8. /// <returns></returns>  
    9. //POST  
    10. ///Admin/Account/Role/SaveRole  
    11. [HttpPost]  
    12. [ValidateInput(false)]  
    13. public ActionResult SaveRole(string role_name, int role_pid, string permission_str, List<int> profession_id)  
    14. {  

    但前提是 同样是:WebConfig HttpRuntime节点 加入 RequestValidateMode 属性,值为2.0(此处2.0并非Framework版本)

    1. <system.web>     
    2.  <httpRuntime requestValidationMode="2.0" /> 
    3. </system.web> 

    validateRequest 可以不需要了。

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5099, 'the-original-on-the-application-of-string-handling-functions-in-c', '浅谈C#中字符串处理函数的应用', '2014-05-12 11:01:25', '2019-03-25 21:29:22', '

    【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

    需求

    前台有一个复杂的tree,在后台只能获取字符串,但是插入数据库是需要id集合

    源字符串如下

    所有权限,系统日志
                                                <select class="easyui-combobox" id="department_id" name="department_id" style="height:20px;"><option selected="selected" value="1">所有部门</option>
    </select>
                                            ,首页最新平台信息,账号信息管理,个人账号管理,企业账号管理   <select class="easyui-combobox" id="profession_id" name="profession_id" style="height:20px;"><option selected="selected" value="1">所有行业</option>
    </select>&nbsp;
                                                                <select class="easyui-combobox" id="profession_id" name="profession_id" style="height:20px;"><option value="1">所有地区</option>
    </select>,企业账号启用禁用功能,管理员账号管理,部门管理,角色管理,简历信息管理
                                               
                                                        <select class="easyui-combobox" id="profession_id" name="profession_id" style="height:20px;"><option selected="selected" value="1">所有行业</option>
    </select>&nbsp;
                                                        <select class="easyui-combobox" id="profession_id" name="profession_id" style="height:20px;"><option value="1">所有地区</option>
    </select>
                                            ,企业资料管理    
                                                        <select class="easyui-combobox" id="profession_id" name="profession_id" style="height:20px;"><option selected="selected" value="1">所有行业</option>
    </select>&nbsp;
                                                        <select class="easyui-combobox" id="profession_id" name="profession_id" style="height:20px;"><option value="1">所有地区</option>
    </select>,企业资料操作栏,企业资料通过审核功能,招聘信息管理
                                                        <select class="easyui-combobox" id="profession_id" name="profession_id" style="height:20px;"><option selected="selected" value="1">所有行业</option>
    </select>&nbsp;
                                                        <select class="easyui-combobox" id="profession_id" name="profession_id" style="height:20px;"><option value="1">所有地区</option>
    </select>,招聘信息操作栏,招聘信息通过审核功能,平台信息管理,合作信息管理,广告管理,充值管理,系统控制面板

    需要拼接成如下字符串

    1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22

    \"QQ截图20140512191028\"

    代码如下

    1. private static void Main(string[] args)  
    2.       {  
    3.           string pstr =  
    4.               System.IO.File.ReadAllText(  
    5.                   "D:\\学习资料\\开发参考资料\\优创科技\\项目\\工作项目\\我的人生网\\源码\\Zhaopin\\UCsoft.Web\\log\\pstr.txt");  
    6.  
    7.           // Console.Write(pstr);  
    8.  
    9.           //string result = NoHtml(pstr);  
    10.           //string result = RemoveHtml(pstr);  
    11.  
    12.           string result = GetPermissionStrs(pstr);  
    13.           result = GetPermissionIds(result);  
    14.  
    15.           Console.Write(result);  
    16.           Console.ReadKey();  
    17.       }  
    18.  
    19.  
    20.       private static string GetPermissionIds(string pstrs)  
    21.       {  
    22.           string[] pstr_arr = pstrs.Split(\',\');  
    23.  
    24.           string result = "";  
    25.  
    26.           ZhaopinEntities zp = new ZhaopinEntities();  
    27.           var dbper = zp.T_user_permission.ToList();  
    28.           foreach (var userPermission in dbper)  
    29.           {  
    30.               foreach (var pstr in pstr_arr)  
    31.               {  
    32.                   if (userPermission.permission_name.Trim()==pstr.Trim())  
    33.                   {  
    34.                       result += userPermission.permission_id + ",";  
    35.                   }  
    36.               }  
    37.           }  
    38.  
    39.           //处理结尾的,  
    40.           if (result.EndsWith(","))  
    41.           {  
    42.               result = result.Substring(0, result.Length - 1);  
    43.           }  
    44.           return result;  
    45.       }  
    46.  
    47.       private static string GetPermissionStrs(string pstr)  
    48.       {  
    49.           //首先去掉字符串之间的所有空格  
    50.           pstr = Regex.Replace(pstr, @"s", "");  
    51.           //然后逐步替换  
    52.           string result = RemoveHtml(pstr);  
    53.           while (result.Contains("select"))  
    54.           {  
    55.               result = RemoveHtml(result);  
    56.           }  
    57.           //最后小处理  
    58.           result = result.Replace("&nbsp;", "");  
    59.           result = result.Replace(",,", ",");  
    60.           //处理结尾的,  
    61.           if (result.EndsWith(","))  
    62.           {  
    63.               result = result.Substring(0, result.Length - 1);  
    64.           }  
    65.           return result;  
    66.       }  
    67.  
    68.       private static string RemoveHtml(string pstr)  
    69.       {  
    70.           string str = StringHelper.SearchString(pstr, "<sel", "t>");  
    71.           string str1 = pstr.Replace(str, "");  
    72.           //删除多余的字符  
    73.           str1 = str1.Replace("<selt>", "");  
    74.           return str1;  
    75.       } 

    数据库的结构

    1. USE [Zhaopin]  
    2. GO  
    3. /****** Object:  Table [dbo].[T_user_role]    Script Date: 05/12/2014 19:00:21 ******/  
    4. SET ANSI_NULLS ON 
    5. GO  
    6. SET QUOTED_IDENTIFIER ON 
    7. GO  
    8. CREATE TABLE [dbo].[T_user_role](  
    9.     [role_id] [int] IDENTITY(1,1) NOT NULL,  
    10.     [role_pid] [int] NULL,  
    11.     [role_type] [bit] NULL,  
    12.     [role_name] [nvarchar](20) NOT NULL,  
    13.  CONSTRAINT [PK_T_USER_ROLE] PRIMARY KEY CLUSTERED   
    14. (  
    15.     [role_id] ASC 
    16. )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]  
    17. ) ON [PRIMARY]  
    18. GO  
    19. EXEC sys.sp_addextendedproperty @name=N\'MS_Description\', @value=N\'角色id\' , @level0type=N\'SCHEMA\',@level0name=N\'dbo\', @level1type=N\'TABLE\',@level1name=N\'T_user_role\', @level2type=N\'COLUMN\',@level2name=N\'role_id\'  
    20. GO  
    21. EXEC sys.sp_addextendedproperty @name=N\'MS_Description\', @value=N\'角色父id\' , @level0type=N\'SCHEMA\',@level0name=N\'dbo\', @level1type=N\'TABLE\',@level1name=N\'T_user_role\', @level2type=N\'COLUMN\',@level2name=N\'role_pid\'  
    22. GO  
    23. EXEC sys.sp_addextendedproperty @name=N\'MS_Description\', @value=N\'角色类型(是否为超级管理员,true:是,false:不是)\' , @level0type=N\'SCHEMA\',@level0name=N\'dbo\', @level1type=N\'TABLE\',@level1name=N\'T_user_role\', @level2type=N\'COLUMN\',@level2name=N\'role_type\'  
    24. GO  
    25. EXEC sys.sp_addextendedproperty @name=N\'MS_Description\', @value=N\'角色名称\' , @level0type=N\'SCHEMA\',@level0name=N\'dbo\', @level1type=N\'TABLE\',@level1name=N\'T_user_role\', @level2type=N\'COLUMN\',@level2name=N\'role_name\'  
    26. GO  
    27. EXEC sys.sp_addextendedproperty @name=N\'MS_Description\', @value=N\'角色表\' , @level0type=N\'SCHEMA\',@level0name=N\'dbo\', @level1type=N\'TABLE\',@level1name=N\'T_user_role\'  
    28. GO  
    29. SET IDENTITY_INSERT [\r\ndbo].[T_user_role] ON 
    30. INSERT [dbo].[T_user_role] ([role_id], [role_pid], [role_type], [role_name]) VALUES (1, 0, 0, N\'超级管理员\')  
    31. INSERT [dbo].[T_user_role] ([role_id], [role_pid], [role_type], [role_name]) VALUES (2, 1, 0, N\'总经理\')  
    32. INSERT [dbo].[T_user_role] ([role_id], [role_pid], [role_type], [role_name]) VALUES (3, 2, 0, N\'经理\')  
    33. INSERT [dbo].[T_user_role] ([role_id], [role_pid], [role_type], [role_name]) VALUES (4, 1, 0, N\'总经理2\')  
    34. INSERT [dbo].[T_user_role] ([role_id], [role_pid], [role_type], [role_name]) VALUES (5, 4, 0, N\'经理2\')  
    35. SET IDENTITY_INSERT [dbo].[T_user_role] OFF 
    36. /****** Object:  Table [dbo].[T_user_role_permission]    Script Date: 05/12/2014 19:00:21 ******/  
    37. SET ANSI_NULLS ON 
    38. GO  
    39. SET QUOTED_IDENTIFIER ON 
    40. GO  
    41. CREATE TABLE [dbo].[T_user_role_permission](  
    42.     [role_id] [int] NOT NULL,  
    43.     [permission_id] [int] NOT NULL,  
    44.     [permission_department] [int] NULL,  
    45.     [permission_profession] [int] NULL,  
    46.     [permission_city] [int] NULL,  
    47.  CONSTRAINT [PK_T_USER_ROLE_PERMISSION] PRIMARY KEY CLUSTERED   
    48. (  
    49.     [role_id] ASC,  
    50.     [permission_id] ASC 
    51. )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]  
    52. ) ON [PRIMARY]  
    53. GO  
    54. EXEC sys.sp_addextendedproperty @name=N\'MS_Description\', @value=N\'角色id\' , @level0type=N\'SCHEMA\',@level0name=N\'dbo\', @level1type=N\'TABLE\',@level1name=N\'T_user_role_permission\', @level2type=N\'COLUMN\',@level2name=N\'role_id\'  
    55. GO  
    56. EXEC sys.sp_addextendedproperty @name=N\'MS_Description\', @value=N\'权限id\' , @level0type=N\'SCHEMA\',@level0name=N\'dbo\', @level1type=N\'TABLE\',@level1name=N\'T_user_role_permission\', @level2type=N\'COLUMN\',@level2name=N\'permission_id\'  
    57. GO  
    58. EXEC sys.sp_addextendedproperty @name=N\'MS_Description\', @value=N\'权限部门(-1:本账号,0:所有,其它:特定)\' , @level0type=N\'SCHEMA\',@level0name=N\'dbo\', @level1type=N\'TABLE\',@level1name=N\'T_user_role_permission\', @level2type=N\'COLUMN\',@level2name=N\'permission_department\'  
    59. GO  
    60. EXEC sys.sp_addextendedproperty @name=N\'MS_Description\', @value=N\'权限行业(-1:不存在,0:所有,其它:特定)\' , @level0type=N\'SCHEMA\',@level0name=N\'dbo\', @level1type=N\'TABLE\',@level1name=N\'T_user_role_permission\', @level2type=N\'COLUMN\',@level2name=N\'permission_profession\'  
    61. GO  
    62. EXEC sys.sp_addextendedproperty @name=N\'MS_Description\', @value=N\'权限地区(-1:不存在,0:所有,其它:特定)\' , @level0type=N\'SCHEMA\',@level0name=N\'dbo\', @level1type=N\'TABLE\',@level1name=N\'T_user_role_permission\', @level2type=N\'COLUMN\',@level2name=N\'permission_city\'  
    63. GO  
    64. EXEC sys.sp_addextendedproperty @name=N\'MS_Description\', @value=N\'角色_权限关系表\' , @level0type=N\'SCHEMA\',@level0name=N\'dbo\', @level1type=N\'TABLE\',@level1name=N\'T_user_role_permission\'  
    65. GO  
    66. INSERT [dbo].[T_user_role_permission] ([role_id], [permission_id], [permission_department], [permission_profession], [permission_city]) VALUES (1, 1, -1, -1, -1)  
    67. INSERT [dbo].[T_user_rol\r\ne_permission] ([role_id], [permission_id], [permission_department], [permission_profession], [permission_city]) VALUES (1, 2, 1, -1, -1)  
    68. INSERT [dbo].[T_user_role_permission] ([role_id], [permission_id], [permission_department], [permission_profession], [permission_city]) VALUES (1, 3, 1, -1, -1)  
    69. INSERT [dbo].[T_user_role_permission] ([role_id], [permission_id], [permission_department], [permission_profession], [permission_city]) VALUES (2, 1, -1, -1, -1)  
    70. INSERT [dbo].[T_user_role_permission] ([role_id], [permission_id], [permission_department], [permission_profession], [permission_city]) VALUES (2, 2, 1, -1, -1)  
    71. INSERT [dbo].[T_user_role_permission] ([role_id], [permission_id], [permission_department], [permission_profession], [permission_city]) VALUES (2, 3, -1, -1, -1)  
    72. INSERT [dbo].[T_user_role_permission] ([role_id], [permission_id], [permission_department], [permission_profession], [permission_city]) VALUES (3, 1, -1, -1, -1)  
    73. INSERT [dbo].[T_user_role_permission] ([role_id], [permission_id], [permission_department], [permission_profession], [permission_city]) VALUES (3, 2, 1, -1, -1)  
    74. INSERT [dbo].[T_user_role_permission] ([role_id], [permission_id], [permission_department], [permission_profession], [permission_city]) VALUES (4, 1, -1, -1, -1)  
    75. INSERT [dbo].[T_user_role_permission] ([role_id], [permission_id], [permission_department], [permission_profession], [permission_city]) VALUES (4, 2, 1, -1, -1)  
    76. INSERT [dbo].[T_user_role_permission] ([role_id], [permission_id], [permission_department], [permission_profession], [permission_city]) VALUES (5, 1, -1, -1, -1)  
    77. INSERT [dbo].[T_user_role_permission] ([role_id], [permission_id], [permission_department], [permission_profession], [permission_city]) VALUES (5, 2, 1, -1, -1)  
    78. /****** Object:  Default [DF__T_user_ro__role___10A1534B]    Script Date: 05/12/2014 19:00:21 ******/  
    79. ALTER TABLE [dbo].[T_user_role] ADD  DEFAULT ((0)) FOR [role_pid]  
    80. GO  
    81. /****** Object:  Default [DF__T_user_ro__permi__137DBFF6]    Script Date: 05/12/2014 19:00:21 ******/  
    82. ALTER TABLE [dbo].[T_user_role_permission] ADD  DEFAULT ((-1)) FOR [permission_department]  
    83. GO  
    84. /****** Object:  Default [DF__T_user_ro__permi__1471E42F]    Script Date: 05/12/2014 19:00:21 ******/  
    85. ALTER TABLE [dbo].[T_user_role_permission] ADD  DEFAULT ((-1)) FOR [permission_profession]  
    86. GO  
    87. /****** Object:  Default [DF__T_user_ro__permi__15660868]    Script Date: 05/12/2014 19:00:21 ******/  
    88. ALTER TABLE [dbo].[T_user_role_permission] ADD  DEFAULT ((-1)) FOR [permission_city]  
    89. GO  
    90. /****** Object:  ForeignKey [FK_T_USER_PERMISSION_REFERENCE_T_USER_PERMISSION]    Script Date: 05/12/2014 19:00:21 ******/  
    91. ALTER TABLE [dbo].[T_user_role_permission]  WITH CHECK ADD  CONSTRAINT [FK_T_USER_PERMISSION_REFERENCE_T_USER_PERMISSION] FOREIGN KEY([permission_id])  
    92. REFERENCES [dbo].[T_user_permission] ([permission_id])  
    93. GO  
    94. ALTER TABLE [dbo].[T_user_role_permission] CHECK CONSTRAINT [FK_T_USER_PERMISSION_REFERENCE_T_USER_PERMISSION]  
    95. GO  
    96. /****** Object:  ForeignKey [FK_T_USER_PERMISSION_REFERENCE_T_USER_ROLE]    Script Date: 05/12/2014 19:00:21 ******/  
    97. ALTER TABLE [dbo].[T_user_role_permission]  WITH CHECK ADD  CONSTRAINT [FK_T_USER_PERMISSION_REFERENCE_T_USER_ROLE] FOREIGN KEY([role_id])  
    98. REFERENCES [dbo].[T_user_role] ([role_id])  
    99. GO  
    100. ALTER TABLE [dbo].[T_user_role_permission\r\n] CHECK CONSTRAINT [FK_T_USER_PERMISSION_REFERENCE_T_USER_ROLE]  
    101. GO  

    存储过程

    1.  
    2. --2014-05-12修改 by 唐有炜  
    3. CREATE PROCEDURE [dbo].[SP_edit_role]  
    4. --角色表(T_user_role)  
    5.     @role_id INT,  
    6.     @role_pid INT,  
    7.     @role_type BIT,  
    8.     @role_name NVARCHAR(20),  
    9.        
    10.      --角色权限映射表(T_user_role_permission)  
    11.      --注意:权限表与此处关联很大,权限表的数据不要轻易修改  
    12.     @permission_ids NVARCHAR(500),  
    13.     @permission_department_log INT, --系统日志涉及的特殊权限  
    14.     @permission_profession_account_company INT, --企业账号行业权限  
    15.     @permission_city_account_company INT, --企业账号地区权限  
    16.     @permission_profession_resume INT, --简历信息行业权限  
    17.     @permission_city_resume INT, --简历信息地区权限  
    18.     @permission_profession_companyinfo INT, --企业资料行业权限  
    19.     @permission_city_companyinfo INT, --企业资料地区权限  
    20.     @permission_profession_employ INT, --招聘信息行业权限  
    21.     @permission_city_employ INT, --招聘信息地区权限  
    22.        
    23.      --输出  
    24.     @status BIT OUTPUT 
    25. AS 
    26.     --分割权限id的相关变量  
    27.     DECLARE @PointerPrev INT   
    28.     DECLARE @PointerCurr INT   
    29.     DECLARE @Pid INT 
    30.     SET @PointerPrev = 1   
    31.       
    32.     --特殊权限相关变量  
    33.     DECLARE @permission_department INT 
    34.     DECLARE @permission_profession INT 
    35.     DECLARE @permission_city INT 
    36.     --设定初始值  
    37.     SET @permission_department = -1  
    38.     SET @permission_profession = -1  
    39.     SET @permission_city = -1  
    40.       
    41.     BEGIN TRANSACTION --开始执行事务  
    42.                       --更新角色表  
    43.     UPDATE [Zhaopin].[dbo].[T_user_role]  
    44.     SET    [role_pid] = @role_pid  
    45.           ,[role_type] = @role_type  
    46.           ,[role_name] = @role_name  
    47.     WHERE  role_id = @role_id  
    48.       
    49.       
    50.     --更新角色权限映射表  
    51.     --先删除所有权限,再逐个添加  
    52.     DELETE   
    53.     FROM   [Zhaopin].[dbo].[T_user_role_permission]  
    54.     WHERE  role_id = @role_id \r\n60;
    55.       
    56.     --逐个添加现有映射  
    57.     --给id字符串加上最后的逗号,便于循环  
    58.     SET @permission_ids = @permission_ids+\',\'  
    59.       
    60.     WHILE (@PointerPrev<LEN(@permission_ids))  
    61.     BEGIN 
    62.         SET @PointerCurr = CHARINDEX(\',\' ,@permission_ids ,@PointerPrev)   
    63.         IF (@PointerCurr>0)  
    64.         BEGIN 
    65.             SET @Pid = CAST(  
    66.                     SUBSTRING(@permission_ids ,@PointerPrev ,@PointerCurr-@PointerPrev)   
    67.                     AS INT 
    68.                 )   
    69.               
    70.             --系统日志部门权限  
    71.             IF (@Pid=2)  
    72.             BEGIN 
    73.                 SET @permission_department = @permission_department_log  
    74.             END--企业账号行业地区权限  
    75.             ELSE   
    76.             IF (@Pid=6)  
    77.             BEGIN 
    78.                 SET @permission_profession = @permission_profession_account_company   
    79.                 SET @permission_city = @permission_city_account_company  
    80.             END--简历信息行业地区权限  
    81.             ELSE   
    82.             IF (@Pid=12)  
    83.             BEGIN 
    84.                 SET @permission_profession = @permission_profession_resume  
    85.                 SET @permission_city = @permission_city_resume  
    86.             END--企业资料行业地区权限  
    87.             ELSE   
    88.             IF (@Pid=13)  
    89.             BEGIN 
    90.                 SET @permission_profession = @permission_profession_companyinfo  
    91.                 SET @permission_city = @permission_city_companyinfo  
    92.             END--招聘信息行业地区权限  
    93.             ELSE   
    94.             IF (@Pid=16)  
    95.             BEGIN 
    96.                 SET @permission_profession = @permission_profession_employ  
    97.                 SET @permission_city = @permission_city_employ  
    98.             END 
    99.               
    100.             --循环提交----------------------------------------------------------  
    101.             INSERT INTO [Zhaopin].[dbo].[T\r\n_user_role_permission]  
    102.               (  
    103.                 [role_id]  
    104.                ,[permission_id]  
    105.                ,[permission_department]  
    106.                ,[permission_profession]  
    107.                ,[permission_city]  
    108.               )  
    109.             VALUES 
    110.               (  
    111.                 @role_id  
    112.                ,@Pid  
    113.                ,@permission_department  
    114.                ,@permission_profession  
    115.                ,@permission_city  
    116.               )  
    117.             ---------------------------------------------------------------------  
    118.               
    119.               
    120.             SET @PointerPrev = @PointerCurr+1  
    121.         END 
    122.         ELSE 
    123.             BREAK  
    124.     END   
    125.       
    126.     IF @@ERROR=0  
    127.     BEGIN 
    128.         SET @status = 1  
    129.         COMMIT TRANSACTION;  
    130.     END 
    131.     ELSE 
    132.     BEGIN 
    133.         SET @status = 0  
    134.         ROLLBACK TRANSACTION;  
    135.     END 
    136. GO  
    137.  
    138.  
    139.  
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5103, 'the-20140513123018', '20140513123018', '2014-05-13 04:26:43', '2019-03-25 21:29:22', '抽时间学习python和node.js', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5104, 'jquery-easyui-set-kindeditor', 'Jquery EasyUI整合KindEditor', '2014-05-14 01:19:59', '2019-03-25 21:29:22', '

    【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

    1.  
    2.  
    3. //Easy UI 整合Kindeditor///////////////////////////////////////////////  
    4. //2014-05-14 修改 by 唐有炜  
    5. (function ($, K) {  
    6.       if (!K)  
    7.           throw "KindEditor未定义!";  
    8.  
    9.     function create(target) {  
    10.         var opts = $.data(target, \'kindeditor\').options;  
    11.         var editor = K.create(target, opts);  
    12.         $.data(target, \'kindeditor\').options.editor = editor;  
    13.     }  
    14.  
    15.     $.fn.kindeditor = function (options, param) {  
    16.         if (typeof options == \'string\') {  
    17.             var method = $.fn.kindeditor.methods[options];  
    18.             if (method) {  
    19.                 return method(this, param);  
    20.             }  
    21.         }  
    22.         options = options || {};  
    23.         return this.each(function () {  
    24.             var state = $.data(this, \'kindeditor\');  
    25.             if (state) {  
    26.                 $.extend(state.options, options);  
    27.             } else {  
    28.                 state = $.data(this, \'kindeditor\', {  
    29.                         options : $.extend({}, $.fn.kindeditor.defaults, $.fn.kindeditor.parseOptions(this), options)  
    30.                     });  
    31.             }  
    32.             create(this);  
    33.         });  
    34.     }  
    35.  
    36.     $.fn.kindeditor.parseOptions = function (target) {  
    37.         return $.extend({}, $.parser.parseOptions(target, []));  
    38.     };  
    39.  
    40.     $.fn.kindeditor.methods = {  
    41.         editor : function (jq) {  
    42.             return $.data(jq[0], \'kindeditor\').options.editor;  
    43.         }  
    44.     };  
    45.  
    46.     $.fn.kindeditor.defaults = {  
    47.         resizeType : 1,  
    48.         allowPreviewEmoticons : false,  
    49.         allowImageUpload : false,  
    50.         items : [  
    51.             \'fontname\', \'fontsize\', \'|\', \'forecolor\', \'hilitecolor\', \'bold\', \'italic\', \'underline\',  
    52.             \'removeformat\', \'|\', \'justifyleft\', \'justifycenter\', \'justifyright\', \'insertorderedlist\',  
    53.             \'insertunorderedlist\', \'|\', \'emoticons\', \'image\', \'link\'],  
    54.         afterChange:function(){  
    55.        &\r\n#160;    this.sync();  
    56.         }  
    57.     };  
    58.     $.parser.plugins.push("kindeditor");  
    59. })(jQuery, KindEditor);  
    60. ////////////////////////////////////////////////// 

     

     

    使用

    1. <textarea name="notice_content" id="notice_content" class="easyui-kindeditor" style="width: 100%; height: 200px; visibility: hidden;">公告内容</textarea> 
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5109, 'method-of-kindeditor-with-js-and-jquery-asynchronous-loading-value-assignment', 'KindEditor用JS和Jquery异步加载方式取值赋值的方法', '2014-05-14 03:37:28', '2019-03-25 21:29:22', '

    【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

     

    1. //检测编辑器  
    2. function checkTextarea() {  
    3.     if ($(".ke-content").html() == "") {  
    4.         $.messager.alert("温馨提示", "公告内容不能为空!", "error");  
    5.         return false;  
    6.     } else {  
    7.         return true;  
    8.     }  
    9. }  
    10.  
    11. //编辑时加载  
    12. function loadTextArea() {  
    13.     //加载KindEditor的第一个实例  
    14.     $(document.getElementsByTagName(\'iframe\')[0].contentWindow.document.body).html("hello");  
    15.     $("#notice_content").html("hello");  
    16. }  
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5111, 'the-20140514191530', '20140514191530', '2014-05-14 11:11:48', '2019-03-25 21:29:22', '弄清楚替换字元。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5112, 'the-20140515001900', '20140515001900', '2014-05-14 16:19:32', '2019-03-25 21:29:22', '不要为了工作而工作,要学会善待自己,追求高品质的生活。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5113, '20140515002335', '20140515002335', '2014-05-14 16:24:02', '2019-03-25 21:29:22', '多把精力放在架构、算法、性能上。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5114, 'the-20140515003117', '20140515003117', '2014-05-14 16:31:45', '2019-03-25 21:29:22', '多把精力放在架构、算法、性能上。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5115, 'the-20140518141225', '20140518141225', '2014-05-18 06:13:03', '2019-03-25 21:29:22', '展示数据的时候,尽量传递id,显示问题由显示逻辑控制。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5117, 'the-20140518144252', '20140518144252', '2014-05-18 06:43:30', '2019-03-25 21:29:22', '问题:日志中的部门动态还是静态。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5120, 'the-original-for-implemented-in-a-sql-statement', '在sql中实现for语句', '2014-05-18 14:25:28', '2019-03-25 21:29:22', '[copy]sql-for[/copy]\r\ndeclare @i int\r\nset @i=0\r\nwhile @i<10\r\nbegin\r\n set @i = @i+1\r\nend\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5122, 'the-return-value-of-ajax-solution-cannot-be-obtained', 'Ajax返回值无法获取的解决方案', '2014-05-19 09:39:07', '2019-03-25 21:29:22', '[copy]the-return-value-of-ajax-solution-cannot-be-obtained[/copy]\r\n\r\n\r\nvar jobs = $.ajax({ url: \"http://localhost:9703/Admin/Resume/Resume/FormateResumeJob/?ids=\" + row.resume_job, async: false }).responseText;\r\n alert(jobs);\r\n row.resume_job = jobs;\r\n\r\n\r\n\r\n getExcepectedJobNames(row, function(data) {\r\n// alert(data);\r\n// });\r\n\r\n\r\n //回调\r\n// function getExcepectedJobNames(r, callback) {\r\n// $.get(\"http://localhost:9703/Admin/Resume/Resume/FormateResumeJob/\" , {\r\n// ids: r.resume_job\r\n// },\r\n// function(data) {\r\n// callback(data);\r\n// }\r\n// );\r\n// }\r\n\r\n\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5129, 'site-configuration-file-flashfxp', 'FlashFXP的站点基本配置文件使用心得', '2014-05-20 14:39:39', '2019-03-25 21:29:22', '

    【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

    FlashFXP的站点配置文件为程序目录下的Sites.dat

    将这个文件复制到别台的机子相应目录,便可得到源机子的FTP配置;

    如果更换PC只需要复制这个文件即可,重新安装同版本的FlashFXP;

    就哦了。

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5132, 'unable-to-the-session-state-server-session-state-request-please-ensure-that-the-asp-net-state-service-asp-net-services-solutions-has-launched', 'Asp .Net Mvc4学习笔记004:无法向会话状态服务器发出会话状态请求。请确保 ASP.NET State Service (ASP.NET 状态服务)已启动“解决方案', '2014-05-21 03:53:59', '2019-03-25 21:29:22', '

    【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

    问题

    在Asp .NET MVC中,使用了Session,但是出现以下错误

    无法向会话状态服务器发出会话状态请求。请确保 ASP.NET State Service (ASP.NET 状态服务)已启动,并且客户端端口与服务器端口相同。如果服务器位于远程计算机上,请检查 HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesaspnet_stateParametersAllowRemoteConnection 的值,确保服务器接受远程请求。如果服务器位于本地计算机上,并且上面提到的注册表值不存在或者设置为 0,则状态服务器连接字符串必须使用“localhost”或“127.0.0.1”作为服务器名称。

    解决方案

    运行 services.msc,将服务 ASP .NET状态服务 启动即可

    \"image\"

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5136, 'asp-net-mvc-using-the-formcollection-form', 'Asp NET MVC利用Formcollection进行表单传值', '2014-05-21 04:14:00', '2019-03-25 21:29:22', '

    【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

    当点击提交按钮后,想在Controller里取到Form里的数据。

    必须在控件上设置name属性 例如

    1. <input name="job_name" type="text" /> 

    在controll的Action里接收如下

    1. #region 添加职位  
    2.        //  
    3.        // GET: /CompanyCenter/JobAdd  
    4.  
    5.        public ActionResult JobAdd()  
    6.        {  
    7.            return View();  
    8.        }  
    9.  
    10.        //  
    11.        // POST: /CompanyCenter/JobAdd  
    12.  
    13.        [HttpPost]  
    14.        public ActionResult JobAdd(FormCollection fc)  
    15.        {  
    16.  
    17.            string job_name = fc["job_name"];  
    18.            return View();  
    19.        }  
    20.        #endregion 

    如果不设置input的name属性,发现action里form总是为空!

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5142, 'to-test-the-forms-using-jquery-validdatemin-js', '利用jquery.validdate.min.js进行表单验证', '2014-05-21 09:25:24', '2019-03-25 21:29:22', '【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】\r\n

    步骤一

    \r\n引用js\r\n
    \r\n
    \r\n
      \r\n
    1. <script src=\"../../Scripts/jquery.validate.min.js\" type=\"text/javascript\"></script>
    2. \r\n
    3. <script src=\"../../Scripts/messages_cn.js\" type=\"text/javascript\"></script>
    4. \r\n
    5. <!--表单验证—>
    6. \r\n
    \r\n
    \r\n

    步骤二

    \r\n书写js\r\n
    \r\n
    \r\n
      \r\n
    1. <script type=\"text/javascript\">
    2. \r\n
    3.        //表单验证
    4. \r\n
    5.        $(function() {
    6. \r\n
    7.            $(\"#form1\").validate({
    8. \r\n
    9.                messages: {
    10. \r\n
    11.                    job_name: {
    12. \r\n
    13.                        required: \"&nbsp;请输入职位名称\"
    14. \r\n
    15.                    }
    16. \r\n
    17.                }
    18. \r\n
    19.            });
    20. \r\n
    21.        });
    22. \r\n
    23.    </script>
    24. \r\n
    \r\n
    \r\n

    步骤三:页面展示

    \r\n
    \r\n
    \r\n
      \r\n
    1. <form id=\"form1\" action=\"/CompanyCenter/JobAdd/\" method=\"POST\">
    2. \r\n
    3.            <div class=\"ljobadd\">
    4. \r\n
    5.                <input type=\"hidden\" id=\"txtJobTypeMLId\" name=\"JobWork\" value=\"\">
    6. \r\n
    7.                <input type=\"hidden\" id=\"txtPlaceMLId\" name=\"JobArea\" value=\"5\">
    8. \r\n
    9.                <div class=\"titlebg\">职位描述</div>
    10. \r\n
    11.                <div class=\"postbank\">
    12. \r\n
    13.                    <div class=\"postsrk\">
    14. \r\n
    15.                        <div class=\"postsrkle\"><span>*</span>职位名称:</div>
    16. \r\n
    17.                        <div class=\"postsrkri\">
    18. \r\n
    19.                            <input name=\"job_name\" type=\"text\" id=\"job_name\" class=\"inputtext srkbg width393 required\">
    20. \r\n
    21.                    </div>
    22. \r\n
    23. </div>
    24. \r\n
    \r\n
    \r\n

    效果预览

    \r\n\"2014-05-21_172229\"\r\n

    验证优化

    \r\n加上以下代码,提升用户体验(2014-06-15 更新 By Terwer)\r\n
    \r\n
    \r\n
      \r\n
    1. success: function (label) {
    2. \r\n
    3.     label.html(\"<span style=\'color:green;\'>&nbsp;输入正确</span>\").addClass(\"chenggong\");
    4. \r\n
    5. },
    6. \r\n
    7. showErrors: function (errorMap, errorList) {
    8. \r\n
    9.     // alert(\"您的表单包含\" + this.numberOfInvalids()
    10. \r\n
    11.     //  + \"项错误,请检查!\");
    12. \r\n
    13.     $(\".error\").next().removeClass(\"chenggong\");
    14. \r\n
    15.     this.defaultShowErrors();
    16. \r\n
    17. },
    18. \r\n
    \r\n
    \r\n \r\n
    \r\n
    \r\n
      \r\n
    1. /* 成功提示 */
    2. \r\n
    3. .chenggong {
    4. \r\n
    5.     displayinline-block;
    6. \r\n
    7.     height16px;
    8. \r\n
    9.     backgroundurl(/Content/themes/home/images/reg-menu.gif) 0 -22px no-repeat;
    10. \r\n
    11.     padding-left15px;
    12. \r\n
    13.     vertical-alignmiddle;
    14. \r\n
    15.     padding-right5px;
    16. \r\n
    17.     margin-left5px;
    18. \r\n
    19. }
    20. \r\n
    \r\n
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5145, 'the-20140521173824', '20140521173824', '2014-05-21 09:39:15', '2019-03-25 21:29:22', '决定在项目前台抛弃easyui直接用jqueryvalidate', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5146, 'the-20140522170333', '20140522170333', '2014-05-22 09:04:31', '2019-03-25 21:29:22', '正式决定转行Android。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5147, 'let-the-virtualbox-virtual-machine-and-the-host-in-the-same-lan-settings', '让virtualbox虚拟机与宿主机在同一局域网的设置', '2014-05-24 13:13:55', '2019-03-25 21:29:22', '

    【版权声明:本文转载自百度经验,版权归原作者。如需转载,请务必在转载时注明原文地址。】

    在virtualbox虚拟机中安装系统后,我们有时候需要与宿主机之间建立通信,能够互相访问。但是我们发现虚拟机的ip和宿主机的ip不在一个ip段,也就是不在一个局域网怎么办呢?

    1. 打开宿主机控制面板-网络和internet-网络连接

      \"让virtualbox虚拟机与宿主机在同一局域网的设置\"
    2. 选中VB安装的虚拟网卡和本地连接,然后在右键菜单中选择“桥接”

      \"让virtualbox虚拟机与宿主机在同一局域网的设置\"

    3. 在virtualbox虚拟机设置界面,选择虚拟机的网络设置,在网络设置窗口,修改连接方式为:桥接,名称为:MAC Bridge Miniport

      \"让virtualbox虚拟机与宿主机在同一局域网的设置\"

    4. 在虚拟机里的网络配置中手动分配一个局域网IP段的ip保存即可。

      \"让virtualbox虚拟机与宿主机在同一局域网的设置\"


    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5150, 'the-20140525014305', '20140525014305', '2014-05-24 17:44:11', '2019-03-25 21:29:22', '每天都要过有创造性的生活。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5151, 'asp-net-mvc-custom-htmlhelper-format-the-displayed-boolean-values', 'ASP .NET MVC自定义HtmlHelper格式化显示Boolean值', '2014-05-24 17:45:54', '2019-03-25 21:29:22', '

    【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

    1. #region Boolean格式化输出  
    2.  
    3.         /// <summary>  
    4.         /// Boolean格式化输出 2014-05-25 By 唐有炜  
    5.         /// </summary>  
    6.         /// <param name="htmlHelper"></param>  
    7.         /// <param name="b"></param>  
    8.         /// <param name="displayNameTrue"></param>  
    9.         /// <param name="displayNameFalse"></param>  
    10.         /// <returns></returns>  
    11.         public static MvcHtmlString BooleanPalse(this HtmlHelper htmlHelper, bool? b, string displayNameTrue,  
    12.             string displayNameFalse)  
    13.         {  
    14.             if ((bool)b)  
    15.             {  
    16.                 return MvcHtmlString.Create(displayNameTrue);  
    17.             }  
    18.             return MvcHtmlString.Create(displayNameFalse);  
    19.         }  
    20.  
    21.         #endregion 

    使用:

    1. <td>@Html.BooleanPalse(emp.employ_status, "发布中", "审核中")</td> 
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5153, 'the-20140525032738', '20140525032738', '2014-05-24 19:28:44', '2019-03-25 21:29:22', '每天都要过有创造性的生活。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5154, 'asp-net-mvc-using-the-htmldropdownlist-data-binding', 'ASP .NET MVC利用Html.DropdownList绑定数据', '2014-05-25 05:27:19', '2019-03-25 21:29:22', '

    【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

    后台:

    1. //显示大行业  
    2.           ViewData["listProfession"] = new SelectList(db.TClassProfessions.Where(p=>p.profession_pid==1).ToList(), "id", "profession_name");  
    3.           //显示地区  
    4.           ViewData["listCity"] = new SelectList(db.TClassCities.Where(c => c.city_pid == 1), "id", "city_name");  
    5.           //注册资金  
    6.           List<SelectListItem> itemsZc = new List<SelectListItem>();  
    7.           itemsZc.Add(new SelectListItem { Text = "50万以下", Value = "1" });  
    8.           //itemsZc.Add(new SelectListItem { Text = "50万~1000万", Value = "2", Selected = true });  
    9.           itemsZc.Add(new SelectListItem { Text = "50万~1000万", Value = "2" });  
    10.           itemsZc.Add(new SelectListItem { Text = "1000万~1亿", Value = "3" });  
    11.           itemsZc.Add(new SelectListItem { Text = "1亿以上", Value = "4" });  
    12.           this.ViewData["listMoney"] = new SelectList(itemsZc,"Value","Text"); 

    前台:

    1. <li><span>注册资金:</span> 
    2.                       @Html.DropDownListFor(model=>model.company_money,ViewData["listMoney"] as SelectList,new {@id="company_money"})  
    3.                       <li><span>所属行业:</span> 
    4.                           @Html.DropDownListFor(model => model.company_profession, ViewData["listProfession"] as SelectList, new {@id = "company_profession"})  
    5.                       </li> 
    6.                       <li><span>所在地区:</span> 
    7.                       @Html.DropDownListFor(model => model.company_address, ViewData["listCity"] as SelectList, new {@id = "company_address"}) 
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5158, 'jquery-ajaxsubmit-does-not-perform-callback-solutions', 'Jquery ajaxSubmit不执行回调解决方案', '2014-05-25 08:04:12', '2019-03-25 21:29:22', '【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】\r\n\r\njquery与jquery.form.js版本不对应,修改就好了。\r\n\r\n我把jquery.min.js换成1.3.2,解决了\r\n\r\nvar submitUrl;\r\n$(\"#form1\").ajaxSubmit({\r\nbeforeSubmit: function(formData, jqForm, options) {\r\n},\r\nsuccess: function(data, textStatus) {\r\n},\r\ncomplete: function() {\r\n//alert(\'任务已经开始执行.....\');\r\n},\r\nerror: function(data, status, e) {\r\n//alert(\"上传失败,错误信息:\" + e);\r\n},\r\nurl: submitUrl,\r\ntype: \"post\",\r\ndataType: \"json\",\r\ntimeout: 600000\r\n});', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5160, 'the-20140526210642', '20140526210642', '2014-05-26 13:08:13', '2019-03-25 21:29:22', '今天测试', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5182, 'java8-new-features-details', 'Java8新特性详解', '2014-06-14 15:51:02', '2019-03-25 21:29:22', '

    【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

    经过2年半的努力、屡次的延期和9个里程碑版本,甲骨文的Java开发团队终于发布了Java 8正式版本。

    \"\"

    Java 8版本最大的改进就是Lambda表达式,其目的是使Java更易于为多核处理器编写代码;其次,新加入的Nashorn引擎也使得Java程序可以和JavaScript代码互操作;再者,新的日期时间API、GC改进、并发改进也相当令人期待。

    另外,原本要加入Java 8的Jigsaw项目(标准模块系统)由于开发时间关系,被推迟到了Java 9中,不过Java 8已经在朝着这个方向努力了。

    Java 8的所有新特性及改进包括(JEP全称为JDK Enhancement Proposal,JDK改进建议):

    语言改进:

    • JEP 126:Lambda表达式 & 虚拟扩展方法
    • JEP 138:基于Autoconf的构建系统
    • JEP 160:针对Method Handles的Lambda形式的表征
    • JEP 161:简洁的配置文件
    • JEP 162:为模块化做准备
    • JEP 164:利用CPU指令来改善AES加密的性能
    • JEP 174:Nashorn引擎,允许在Java程序中嵌入JS代码
    • JEP 176:自动检测识别Caller-Sensitive方法
    • JEP 179:JDK API变化和稳定性记录

    VM基础改进:

    • JEP 142:减少指定字段上的缓存争用

    VM垃圾回收(vm/gc)改进:

    • JEP 122:移除Permanent Generation(永久代)
    • JEP 173:移除一些很少使用的垃圾回收器组合

    VM运行时(vm/rt)改进:

    • JEP 136:提供更多的验证错误信息
    • JEP 147:减少类元数据封装
    • JEP 148:支持创建小型虚拟机(3M以下)
    • JEP 171:添加3个内存有序化的内联函数

    核心基础(core)改进:

    • JEP 153:命令行启动JavaFX应用

    核心lang(core/lang)改进:

    • JEP 101:目标类型推断
    • JEP 104:Java类型注解
    • JEP 105:DocTree API
    • JEP 106:在javax.tools中添加Javadoc
    • JEP 117:移除APT(Annotation-Processing Tool)
    • JEP 118:运行过程中可访问参数名
    • JEP 120:重复注解
    • JEP 139:增强了javac,以改善构建速度
    • JEP 172:DocLint工具,用来检查Javadoc注释内容

    核心库(core/libs)改进:

    • JEP 103:并行数组排序
    • JEP 107:集合数据批量操作
    • JEP 109:增强的包含Lambda的核心库
    • JEP 112:改进了字符集的实现
    • JEP 119:Core Reflection提供的javax.lang.model实现
    • JEP 135:Base64编解码
    • JEP 149:减少了核心库的内存占用
    • JEP 150:日期时间API
    • JEP 155:改进对并发的支持
    • JEP 170:JDBC 4.2
    • JEP 177:java.text.DecimalFormat.format优化
    • JEP 178:静态链接的JNI库
    • JEP 180:使用平衡树处理频繁的HashMap碰撞

    核心i18n(core/i18n)改进:

    • JEP 127:改进了本地数据封装,采用Unicode CLDR数据
    • JEP 128:BCP 47局部匹配
    • JEP 133:Unicode 6.2

    核心net(core/net)改进:

    核心安全(core/sec)改进:

    • JEP 113:MS-SFU Kerberos 5扩展
    • JEP 114:TLS Server Name Indication(SNI)扩展
    • JEP 115:AEAD密码套件
    • JEP 121:更强的口令加密系统算法
    • JEP 123:可配置的安全随机数生成方法
    • JEP 124:增强了证书撤回检测API
    • JEP 129NSA Suite B加密算法实现
    • JEP 130:SHA-224消息摘要算法实现
    • JEP 131:针对64位Windows的SunPKCS11加密提供程序
    • JEP 140:特权限制
    • JEP 166:彻底检修JKS-JCEKS-PKCS12密钥库

    web/jaxp改进:

    • JEP 185:JAXP 1.5(限制获取外部资源)

    详细信息http://openjdk.java.net/projects/jdk8/features

    JDK 8下载https://jdk8.java.net/

    同时发布的还有NetBeans IDE 8.0正式版本,新版本特性见:NetBeans IDE 8.0 新特性一览

    \r\n

    原文链接:http://www.iteye.com/news/28870-java-8-release

    【编辑推荐】

    1. Java 8特性探究(二)深入解析默认方法
    2. Java 8是否还需要LINQ?还是已经比LINQ 更好?
    3. 甲骨文限制Java 9对Java 8的向下兼容能力
    4. Java 8最终发布日期敲定,有bug也要发布
    5. IntelliJ IDEA 13.1 RC2 完成 Java 8 的最终支持
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5187, '5187', 'Jquery Validate学习笔记', '2014-06-15 06:10:14', '2019-03-25 21:29:22', '

    使用方法

    详见我的另一篇博文利用jquery.validdate.min.js进行表单验证

    定义中文提示信息

    //定义中文消息
    var cnmsg = {
    required: “必选字段”,
    remote: “请修正该字段”,
    email: “请输入正确格式的电子邮件”,
    url: “请输入合法的网址”,
    date: “请输入合法的日期”,
    dateISO: “请输入合法的日期 (ISO).”,
    number: “请输入合法的数字”,
    digits: “只能输入整数”,
    creditcard: “请输入合法的信用卡号”,
    equalTo: “请再次输入相同的值”,
    accept: “请输入拥有合法后缀名的字符串”,
    maxlength: jQuery.format(“请输入一个长度最多是 {0} 的字符串”),
    minlength: jQuery.format(“请输入一个长度最少是 {0} 的字符串”),
    rangelength: jQuery.format(“请输入一个长度介于 {0} 和 {1} 之间的字符串”),
    range: jQuery.format(“请输入一个介于 {0} 和 {1} 之间的值”),
    max: jQuery.format(“请输入一个最大为 {0} 的值”),
    min: jQuery.format(“请输入一个最小为 {0} 的值”)
    };
    jQuery.extend(jQuery.validator.messages, cnmsg);


    Jquery Validate 验证规则

    (1)required:true  必输字段
    (2)remote:”check.php”  使用ajax方法调用check.php验证输入值
    (3)email:true  必须输入正确格式的电子邮件
    (4)url:true  必须输入正确格式的网址
    (5)date:true  必须输入正确格式的日期
    (6)dateISO:true  必须输入正确格式的日期(ISO),例如:2009-06-23,1998/01/22 只验证格式,不验证有效性
    (7)number:true  必须输入合法的数字(负数,小数)
    (8)digits:true  必须输入整数
    (9)creditcard:  必须输入合法的信用卡号
    (10)equalTo:”#field”  输入值必须和#field相同
    (11)accept:  输入拥有合法后缀名的字符串(上传文件的后缀)
    (12)maxlength:5  输入长度最多是5的字符串(汉字算一个字符)
    (13)minlength:10  输入长度最小是10的字符串(汉字算一个字符)
    (14)rangelength:[5,10]  输入长度必须介于 5 和 10 之间的字符串”)(汉字算一个字符)
    (15)range:[5,10]  输入值必须介于 5 和 10 之间
    (16)max:5  输入值不能大于5
    (17)min:10  输入值不能小于10


    Jquery Validate 自定义验证规则

    addMethod(name,method,message)方法:
    参数name 是添加的方法的名字
    参数method是一个函数,接收三个参数(value,element,param) value 是元素的值,element是元素本身 param
    是参数,我们可以用addMethod 来添加除built-in Validation methods 之外的验证方法比如有一个字段,只
    能输一个字母,范围是a-f,写法如下:

    $.validator.addMethod(“af”,function(value,element,params){
    if(value.length>1){
    return false;
    }
    if(value>=params[0] && value<=params[1]){
    return true;
    }else{
    return false;
    }
    },”必须是一个字母,且a-f”);
    用的时候,比如有个表单字段的id=”username”,则在rules 中写
    username:{
    af:["a","f"]
    }
    方法
    addMethod 的第一个参数,就是添加的验证方法的名子,这时是af
    addMethod 的第三个参数,就是自定义的错误提示,这里的提示为:”必须是一个字母,且a-f”
    addMethod 的第二个参数,是一个函数,这个比较重要,决定了用这个验证方法时的写法
    如果只有一个参数,直接写,如果af:”a”,那么a 就是这个唯一的参数,如果多个参数,用在[]里,用逗号分开


    Jquery Validate submit 提交
    submitHandler: 通过验证后运行的函数,里面要加上表单提交的函 数,否则表单不会提交
    \r\n\r\n
    $(".selector").validate({ submitHandler:function(form) { $(form).ajaxSubmit(); //用Jquery Form的函数 } })
    \r\n\r\n
    \r\n\r\n
    Jquery Validate error 错误提示dom
    \r\n\r\n

    .errorPlacement:Callback Default: 把错误信息放在验证的元素后面\r\n
    指明错误放置的位置,默认情况是:error.appendTo(element.parent());即把错误信息放在验证的元素后面\r\n\r\n
    errorPlacement: function(error, element) {\r\n\r\n
    error.appendTo(element.parent());\r\n\r\n
    }

    \r\n\r\n

    设置错误提示的样式,可以增加图标显示,like:

    \r\n\r\n

    input.error { border: 1px solid red; }\r\n
    label.error {\r\n\r\n
    background:url(“./demo/images/unchecked.gif”) no-repeat 0px 0px;

    \r\n\r\n

    padding-left: 16px;

    \r\n\r\n

    padding-bottom: 2px;

    \r\n\r\n

    font-weight: bold;

    \r\n\r\n

    color: #EA5200;\r\n
    }

    \r\n\r\n
    \r\n\r\n
    附录:常用的自定义验证规则
    \r\n\r\n

    // 字符验证\r\n\r\n
    jQuery.validator.addMethod(“stringCheck”, function(value, element) {\r\n\r\n
    return this.optional(element) || /^[u0391-uFFE5w]+$/.test(value);\r\n\r\n
    }, ”只能包括中文字、英文字母、数字和下划线”);

    \r\n\r\n

    // 中文字两个字节\r\n\r\n
    jQuery.validator.addMethod(“byteRangeLength”, function(value, element, param) {\r\n\r\n
    var length = value.length;\r\n\r\n
    for(var i = 0; i < value.length; i++){\r\n\r\n
    if(value.charCodeAt(i) > 127){\r\n\r\n
    length++;\r\n\r\n
    }\r\n\r\n
    }\r\n\r\n
    return this.optional(element) || ( length >= param[0] && length <= param[1] );\r\n\r\n
    }, ”请确保输入的值在3-15个字节之间(一个中文字算2个字节)”);

    \r\n\r\n

    // 身份证号码验证\r\n\r\n
    jQuery.validator.addMethod(“isIdCardNo”, function(value, element) {\r\n\r\n
    return this.optional(element) || isIdCardNo(value);\r\n\r\n
    }, ”请正确输入您的身份证号码”);

    \r\n\r\n

    // 手机号码验证\r\n\r\n
    jQuery.validator.addMethod(“isMobile”, function(value, element) {\r\n\r\n
    var length = value.length;\r\n\r\n
    var mobile = /^(((13[0-9]{1})|(15[0-9]{1}))+d{8})$/;\r\n\r\n
    return this.optional(element) || (length == 11 && mobile.test(value));\r\n\r\n
    }, ”请正确填写您的手机号码”);

    \r\n\r\n

    // 电话号码验证\r\n\r\n
    jQuery.validator.addMethod(“isTel”, function(value, element) {\r\n\r\n
    var tel = /^d{3,4}-?d{7,9}$/;  //电话号码格式010-12345678\r\n\r\n
    return this.optional(element) || (tel.test(value));\r\n\r\n
    }, ”请正确填写您的电话号码”);

    \r\n\r\n

    // 联系电话(手机/电话皆可)验证\r\n\r\n
    jQuery.validator.addMethod(“isPhone”, function(value,element) {\r\n\r\n
    var length = value.length;\r\n\r\n
    var mobile = /^(((13[0-9]{1})|(15[0-9]{1}))+d{8})$/;\r\n\r\n
    var tel = /^d{3,4}-?d{7,9}$/;\r\n\r\n
    return this.optional(element) || (tel.test(value) || mobile.test(value));

    \r\n\r\n

    }, ”请正确填写您的联系电话”);

    \r\n\r\n

    // 邮政编码验证\r\n\r\n
    jQuery.validator.addMethod(“isZipCode”, function(value, element) {\r\n\r\n
    var tel = /^[0-9]{6}$/;\r\n\r\n
    return this.optional(element) || (tel.test(value));\r\n\r\n
    }, ”请正确填写您的邮政编码”);

    \r\n\r\n

    function isIdCardNo(num) {

    \r\n\r\n

    var factorArr = new Array(7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2,1);\r\n
    var parityBit=new Array(“1″,”0″,”X”,”9″,”8″,”7″,”6″,”5″,”4″,”3″,”2″);\r\n\r\n
    var varArray = new Array();\r\n\r\n
    var intValue;\r\n\r\n
    var lngProduct = 0;\r\n\r\n
    var intCheckDigit;\r\n\r\n
    var intStrLen = num.length;\r\n\r\n
    var idNumber = num;\r\n\r\n
    // initialize\r\n\r\n
    if ((intStrLen != 15) && (intStrLen != 18)) {\r\n\r\n
    return false;\r\n\r\n
    }\r\n\r\n
    // check and set value\r\n\r\n
    for(i=0;i<intStrLen;i++) {\r\n\r\n
    varArray[i] = idNumber.charAt(i);\r\n\r\n
    if ((varArray[i] < ’0′ || varArray[i] > ’9′) && (i != 17)) {\r\n\r\n
    return false;\r\n\r\n
    } else if (i < 17) {\r\n\r\n
    varArray[i] = varArray[i] * factorArr[i];\r\n\r\n
    }\r\n\r\n
    }

    \r\n\r\n

    if (intStrLen == 18) {\r\n
    //check date\r\n\r\n
    var date8 = idNumber.substring(6,14);\r\n\r\n
    if (isDate8(date8) == false) {\r\n\r\n
    return false;\r\n\r\n
    }\r\n\r\n
    // calculate the sum of the products\r\n\r\n
    for(i=0;i<17;i++) {\r\n\r\n
    lngProduct = lngProduct + varArray[i];\r\n\r\n
    }\r\n\r\n
    // calculate the check digit\r\n\r\n
    intCheckDigit = parityBit[lngProduct % 11];\r\n\r\n
    // check last digit\r\n\r\n
    if (varArray[17] != intCheckDigit) {\r\n\r\n
    return false;\r\n\r\n
    }\r\n\r\n
    }\r\n\r\n
    else{  //length is 15\r\n\r\n
    //check date\r\n\r\n
    var date6 = idNumber.substring(6,12);\r\n\r\n
    if (isDate6(date6) == false) {

    \r\n\r\n

    return false;\r\n
    }\r\n\r\n
    }\r\n\r\n
    return true;

    \r\n\r\n

    }\r\n
    function isDate6(sDate) {\r\n\r\n
    if(!/^[0-9]{6}$/.test(sDate)) {\r\n\r\n
    return false;\r\n\r\n
    }\r\n\r\n
    var year, month, day;\r\n\r\n
    year = sDate.substring(0, 4);\r\n\r\n
    month = sDate.substring(4, 6);\r\n\r\n
    if (year < 1700 || year > 2500) return false\r\n\r\n
    if (month < 1 || month > 12) return false\r\n\r\n
    return true\r\n\r\n
    }\r\n\r\n
    function isDate8(sDate) {\r\n\r\n
    if(!/^[0-9]{8}$/.test(sDate)) {\r\n\r\n
    return false;\r\n\r\n
    }\r\n\r\n
    var year, month, day;\r\n\r\n
    year = sDate.substring(0, 4);\r\n\r\n
    month = sDate.substring(4, 6);\r\n\r\n
    day = sDate.substring(6, 8);\r\n\r\n
    var iaMonthDays = [31,28,31,30,31,30,31,31,30,31,30,31]\r\n\r\n
    if (year < 1700 || year > 2500) return false\r\n\r\n
    if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) iaMonthDays[1]=29;\r\n\r\n
    if (month < 1 || month > 12) return false\r\n\r\n
    if (day < 1 || day > iaMonthDays[month - 1]) return false\r\n\r\n
    return true\r\n\r\n
    }\r\n\r\n
    // 身份证号码验证  \r\n\r\n
    jQuery.validator.addMethod(“idcardno”, function(value, element) {\r\n\r\n
    return this.optional(element) || isIdCardNo(value);\r\n\r\n
    }, “请正确输入身份证号码”);

    \r\n\r\n

    //字母数字\r\n\r\n
    jQuery.validator.addMethod(“alnum”, function(value, element) {\r\n\r\n
    return this.optional(element) || /^[a-zA-Z0-9]+$/.test(value);\r\n\r\n
    }, “只能包括英文字母和数字”);

    \r\n\r\n

    // 邮政编码验证\r\n\r\n
    jQuery.validator.addMethod(“zipcode”, function(value, element) {\r\n\r\n
    var tel = /^[0-9]{6}$/;\r\n\r\n
    return this.optional(element) || (tel.test(value));\r\n\r\n
    }, “请正确填写邮政编码”);

    \r\n\r\n

    // 汉字\r\n\r\n
    jQuery.validator.addMethod(“chcharacter”, function(value, element) {\r\n\r\n
    var tel = /^[u4e00-u9fa5]+$/;\r\n\r\n
    return this.optional(element) || (tel.test(value));\r\n\r\n
    }, “请输入汉字”);

    \r\n\r\n

    // 字符最小长度验证(一个中文字符长度为2)\r\n\r\n
    jQuery.validator.addMethod(“stringMinLength”, function(value, element, param) {\r\n\r\n
    var length = value.length;\r\n\r\n
    for ( var i = 0; i < value.length; i++) {\r\n\r\n
    if (value.charCodeAt(i) > 127) {\r\n\r\n
    length++;\r\n\r\n
    }\r\n\r\n
    }\r\n\r\n
    return this.optional(element) || (length >= param);\r\n\r\n
    }, $.validator.format(“长度不能小于{0}!”));

    \r\n\r\n

    // 字符最大长度验证(一个中文字符长度为2)\r\n\r\n
    jQuery.validator.addMethod(“stringMaxLength”, function(value, element, param) {\r\n\r\n
    var length = value.length;\r\n\r\n
    for ( var i = 0; i < value.length; i++) {\r\n\r\n
    if (value.charCodeAt(i) > 127) {\r\n\r\n
    length++;\r\n\r\n
    }\r\n\r\n
    }\r\n\r\n
    return this.optional(element) || (length <= param);\r\n\r\n
    }, $.validator.format(“长度不能大于{0}!”));

    \r\n\r\n

    // 字符验证\r\n\r\n
    jQuery.validator.addMethod(“string”, function(value, element) {\r\n\r\n
    return this.optional(element) || /^[u0391-uFFE5w]+$/.test(value);\r\n\r\n
    }, “不允许包含特殊符号!”);

    \r\n\r\n

    // 手机号码验证\r\n\r\n
    jQuery.validator.addMethod(“mobile”, function(value, element) {\r\n\r\n
    var length = value.length;\r\n\r\n
    return this.optional(element) || (length == 11 && /^(((13[0-9]{1})|(15[0-9]{1}))+d{8})$/.test(value));\r\n\r\n
    }, “手机号码格式错误!”);

    \r\n\r\n

    // 电话号码验证\r\n\r\n
    jQuery.validator.addMethod(“phone”, function(value, element) {\r\n\r\n
    var tel = /^(d{3,4}-?)?d{7,9}$/g;\r\n\r\n
    return this.optional(element) || (tel.test(value));\r\n\r\n
    }, “电话号码格式错误!”);

    \r\n\r\n

    // 邮政编码验证\r\n\r\n
    jQuery.validator.addMethod(“zipCode”, function(value, element) {\r\n\r\n
    var tel = /^[0-9]{6}$/;\r\n\r\n
    return this.optional(element) || (tel.test(value));\r\n\r\n
    }, “邮政编码格式错误!”);

    \r\n\r\n

    // 必须以特定字符串开头验证\r\n\r\n
    jQuery.validator.addMethod(“begin”, function(value, element, param) {\r\n\r\n
    var begin = new RegExp(“^” + param);\r\n\r\n
    return this.optional(element) || (begin.test(value));\r\n\r\n
    }, $.validator.format(“必须以 {0} 开头!”));

    \r\n\r\n

    // 验证两次输入值是否不相同\r\n\r\n
    jQuery.validator.addMethod(“notEqualTo”, function(value, element, param) {\r\n\r\n
    return value != $(param).val();\r\n\r\n
    }, $.validator.format(“两次输入不能相同!”));

    \r\n\r\n

    // 验证值不允许与特定值等于\r\n\r\n
    jQuery.validator.addMethod(“notEqual”, function(value, element, param) {\r\n\r\n
    return value != param;\r\n\r\n
    }, $.validator.format(“输入值不允许为{0}!”));

    \r\n\r\n

    // 验证值必须大于特定值(不能等于)\r\n\r\n
    jQuery.validator.addMethod(“gt”, function(value, element, param) {\r\n\r\n
    return value > param;\r\n\r\n
    }, $.validator.format(“输入值必须大于{0}!”));

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5189, '5189', '解决linux的-bash: ./xx.sh: Permission denied', '2014-06-15 06:45:32', '2019-03-25 21:29:22', '

    在linux下执行sh文件时提示下面信息:
    -bash: ./xx.sh: Permission denied
    解决:
    chmod 777 xx.sh

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5198, 'original-js-ie8-compatible-string-trim-method', 'js在IE8+兼容String没有trim方法', '2014-06-20 06:23:20', '2019-03-25 21:29:22', '

    前几天在写js时候发现String的trim 方法报错,从网上找到资料才知道原来IE8下String没有trim方法。。
    兼容很简单,在你的js代码前加上如下代码:

    1. String.prototype.trim = function(){ return Trim(this);}; 
    2. function LTrim(str) 
    3. var i; 
    4. for(i=0;i<str.length;i++) 
    5. if(str.charAt(i)!=" "&&str.charAt(i)!=" ")break
    6. str=str.substring(i,str.length); 
    7. return str; 
    8. function RTrim(str) 
    9. var i; 
    10. for(i=str.length-1;i>=0;i--) 
    11. if(str.charAt(i)!=" "&&str.charAt(i)!=" ")break
    12. str=str.substring(0,i+1); 
    13. return str; 
    14. function Trim(str) 
    15. return LTrim(RTrim(str)); 

    另一种解决方案:

    var pstr = $("#show_list ul").html().trim();
            //alert(pstr.length);
            if(/^s*$/.test(pstr)){
           //if (pstr == "") {
                alert("图片不能为空!");
                return false;
            }

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5202, 'net-mvc4-through-a-custom-filter-login-authentication', '.NET MVC4通过自定义过滤器实现登陆验证', '2014-06-21 01:27:45', '2019-03-25 21:29:22', '
    1. #region 自定义过滤器实现登陆验证 
    2.  
    3.         /// <summary> 
    4.         /// 自定义过滤器实现登陆验证 
    5.         /// </summary> 
    6.         public class UserAuthorizeAttribute : FilterAttribute, IAuthorizationFilter 
    7.         { 
    8.             public void OnAuthorization(AuthorizationContext filterContext) 
    9.             { 
    10.                 //检查是否登录 
    11.                 if (filterContext.HttpContext.Session[UCKeys.SESSION_COMPANY_INFO] == null
    12.                 { 
    13.                     filterContext.Result = new HttpUnauthorizedResult(); //返回未授权Result 
    14.                     //跳转到登录页面 
    15.                     filterContext.HttpContext.Response.Redirect("/CompanyCenter/Login/"); 
    16.                 } 
    17.                 else 
    18.                 { 
    19.                     comp = (VAccountCompany)filterContext.HttpContext.Session[UCKeys.SESSION_COMPANY_INFO]; 
    20.                 } 
    21.             } 
    22.         } 
    23.  
    24.         #endregion 
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5207, 'mvc4-use-entityframework-occurred-when-returning-json-data-while-serializing-an-object-of-type-xx-detects-circular-references-solution', 'MVC4使用EntityFramework返回Json数据时出现“序列化类型为XX的对象时检测到循环引用”解决方案', '2014-06-26 02:27:52', '2019-03-25 21:29:22', '

      在MVC项目中,返回一个JsonResult时,经常报序列化类型为XX的对象时检测到循环引用。

      \"2014-06-26_102946\"

      网上找到个不错的解决方法:

    1.  public class JsonNetResult : JsonResult 
    2.     { 
    3.         public JsonSerializerSettings Settings { get; private set; } 
    4.   
    5.         public JsonNetResult() 
    6.         { 
    7.             Settings = new JsonSerializerSettings 
    8.             { 
    9.                 //这句是解决问题的关键,也就是json.net官方给出的解决配置选项. 
    10.                 ReferenceLoopHandling = ReferenceLoopHandling.Ignore 
    11.             }; 
    12.         } 
    13.   
    14.         public override void ExecuteResult(ControllerContext context) 
    15.         { 
    16.             if (context == null
    17.                 throw new ArgumentNullException("context"); 
    18.             if (this.JsonRequestBehavior == JsonRequestBehavior.DenyGet &&  
    19.             string.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase)) 
    20.                 throw new InvalidOperationException("JSON GET is not allowed"); 
    21.             HttpResponseBase response = context.HttpContext.Response; 
    22.             response.ContentType = string.IsNullOrEmpty(this.ContentType) ? 
    23.              "application/json" : this.ContentType; 
    24.             if (this.ContentEncoding != null
    25.                 response.ContentEncoding = this.ContentEncoding; 
    26.             if (this.Data == null
    27.                 return
    28.             var scriptSerializer = JsonSerializer.Create(this.Settings); 
    29.             using (var sw = new StringWriter()) 
    30.             { 
    31.                 scriptSerializer.Serialize(sw, this.Data); 
    32.                 response.Write(sw.ToString()); 
    33.             } 
    34.         } 
    35.     } 

     

     

    1. public class BaseController : Controller 
    2.    { 
    3.        protected override JsonResult Json(object data, string contentType, Encoding contentEncoding,  
    4.        JsonRequestBehavior behavior) 
    5.   &\r\n#160;    { 
    6.            return new JsonNetResult 
    7.            { 
    8.                Data = data, 
    9.                ContentType = contentType, 
    10.                ContentEncoding = contentEncoding, 
    11.                JsonRequestBehavior = behavior 
    12.            }; 
    13.        } 
    14.  
    15.    } 
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5210, 'mvc-binding-summary', '.NET MVC4常用绑定总结', '2014-06-26 04:47:25', '2019-03-25 21:29:22', '

    【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

    fgf

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5216, 'automatically-sets-the-values-of-the-select-method', 'select自动赋值的方法', '2014-06-26 07:36:49', '2019-03-25 21:29:22', '

    【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

    1. //============================================== 
    2.   //============================================== 
    3.   //select自动赋值 
    4.   //2014-06-26 修改 By 唐有炜 
    5.   //页面使用方法 
    6.   //注意:需要引用jquery.min.js 
    7.   //首先初始化select的所有值(动态静态均可),在要使用的select上方放置一个 <input type="hidden" class="select-hidden" value="select的值"/>,存放select的值(注意:必须有 class="select-hidden",value值必须在select的列表中存在),将这段代码放在$(document).ready(function (){});里面,select就会自动选中。 
    8.   //范例: 
    9.   //<input type="hidden" class="select-hidden" value="@Model.job_sexType"/> 
    10.   //<select name="job_sexType" id="job_sexType" class="resumetbox srkbg space01 width124 required"> 
    11.   //<option  value="0">不限</option> 
    12.   //<option selected="selected" value="1">男</option> 
    13.   //<option  value="2">女</option> 
    14.   //</select> 
    15.   //初始化所有的select值 
    16.   $("select").each(function() { 
    17.       var val = $(this).prev().val(); 
    18.       if (val != undefined) { 
    19.           if ($(this).prev().attr("class").indexOf("select-hidden") >= 0) { 
    20.               $(this).find("option[value=\'" + val + "\']").attr("selected", true); 
    21.           }   
    22.       }  
    23.   }); 
    24.   //============================================== 
    25.   //============================================= 
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5222, 'centos-install-node-js', 'Nodejs学习笔记001:CentOS安装Node.js(Linux源码编译安装)', '2014-06-29 08:10:22', '2019-03-25 21:29:22', '

    【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

    环境准备

    CentOS 6.5 (Linux 2.6.32)

    \"2014-06-29_220342\"
    下载Node.js安装包,请参考网址:http://nodejs.org/download/

    \"FastStoneEditor\"

    下载地址:http://nodejs.org/dist/v0.10.29/node-v0.10.29.tar.gz

    这里选择源码包安装方式。

    安装过程

    登陆到Linux终端,进入/usr/local/src目录,如下:

    [root@localhost ~]#  cd /usr/local/src/

    下载nodejs源码:

    [root@localhost ~]#  wget http://nodejs.org/dist/v0.10.29/node-v0.10.29.tar.gz

    解压文件:

    [root@localhost ~]#  tar xvf node-v0.10.29.tar.gz

    配置并检查安装环境:

    [root@localhost ~]#   cd node-v0.10.29

    [root@localhost ~]#   ./configure

    编译并安装:

    [root@localhost ~]# make

    [root@localhost ~]# make install

    [root@localhost ~]# cp /usr/local/bin/node /usr/sbin/

    查看当前安装的Node的版本 :

    [root@localhost ~]#  node -v

    v0.10.29

    至此,安装成功。

    附:Hello World

    编写hello.js

    1. var http = require(\'http\');  
    2.  
    3.       http.createServer(function (req, res) {  
    4.         res.writeHead(200, {\'Content-Type\': \'text/plain\'});  
    5.         res.end(\'Hello Worldn\');  
    6.       }).listen(1337);  
    7.       console.log(\'Server running at  port 1337 \');  

    执行node hello.js

    打开 http://www.terwer.com:1337/

    \"QQ截图20140701143516\"

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5229, 'java-filter-to-achieve-301-redirect', 'Java利用Filter实现301重定向', '2014-06-30 07:50:22', '2019-03-25 21:29:22', '【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】\r\n

    Filter

    \r\n
    \r\n
    \r\n
      \r\n
    1. import javax.servlet.*;
    2. \r\n
    \r\n
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5238, 'entity-framework-linkqit-realization-of-the-use-of-or', 'Entity Framework利用LINQKit实现Or', '2014-07-03 06:23:51', '2019-03-25 21:29:22', '【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】\r\n

    使用方法

    \r\n引用LINQKit.dll\r\n
    下载地址如下(如果下载链接失效,请与新价值网站长QQ号1035136784联系,我会尽快修复。)
    \r\n
    \"\"
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5246, 'easyui-get-select-value', 'EasyUI获取select的值', '2014-07-09 02:45:34', '2019-03-25 21:29:22', '

    【版权声明:本文为新价值网原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

    错误做法

    以前总是用.val()来获取,可是用easyui这样是不行的,下列方式是错误的的,获取不到select的值:

    1. $("#search_type").val() 

    正确做法

    1. $("#search_type").combobox("getValue"
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5249, 'the-type-has-been-mapped-more-han-once', '一个令人抓狂的错误:The type 'XXX' has been mapped more than once.', '2014-07-10 02:48:41', '2019-03-25 21:29:22', '

    错误重现

    最近新项目上线了,使用的是.NET MVC4和Entity Framework,本地访问一直很好,但是集体测试就时不时出现了下面的错误:

    \"FastStoneEditor\"

    错误原因

    仔细分析了下,发现我在项目中犯了一个致命的错误:使用了全局数据库操作上下文

    原理分析

    未完待续

    解决方案

    在每一次使用数据库操作语句时都加上下面的代码

    // this method is called from several threads concurrently\r\npublic void IncrementProperty()\r\n{\r\n   using (var context = new MyEntities())\r\n   {\r\n      context.SomeObject.SomeIntProperty++;\r\n      context.SaveChanges();\r\n   }\r\n}
    \r\n\r\n
    相关文章:entityframework并发处理
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5256, 'win7-install-node-js', 'Nodejs学习笔记002:Win7安装Node.js', '2014-07-14 05:37:23', '2019-03-25 21:29:22', '

    【版权声明:本文转载自http://blog.baiwand.com/,版权归原作者。如需转载,请务必在转载时注明原文地址。】

    安装

    我这是写的东西也是非常的简单,如何使用Node.js输出 Hello World.

    没错就是hello world.

    下载Node.js

    那开始吧,首先下载Node.js安装包。

    Node.js官网地址 http://nodejs.org/

    \"\"

         然后选择

    \"\"

       不清楚自己电脑是多少位的, 我的电脑》属性--就可以看到了。

       我下载的是Windows Installer(.msi) 32-bit

       把这个东西下载下来,\"\"

      安装

      安装我就不做解释了,默认的安装地址是C:Program Files nodejs

      为了方便开发,可以直接把整个nodejs的文件夹复制/剪切  放到你喜欢的盘里面。

      我直接把nodejs文件夹剪切到E盘根目录,直接修改了文件夹的名字,命名node

    \"\"

    初体验

    接下来就是写代码

      我为了图方便就直接在node下面直接新建了一个hello.js文件

    \"\"

    Hello.js里面

    var sys = require("sys"),  (配置“服务器”)
    http = require("http");
    http.createServer(function(request, response) {  
    response.writeHead(200, {"Content-Type": "text/html"});
    response.write("Hello World!");
    response.end();
    }).listen(8083);
    sys.puts("My first Node.js code.");
    sys.puts("Server running at http://localhost:8083/");

    其中sys.puts可要可不要,只是个提示。

    接下来就是要用一个程序来承载这个Hello.js,  \"\"

    接下来是见证奇迹的时刻,打开网页在地址栏里面输入 http://localhost:8083/

    结果如下:

    \"\"

    (小白)体验中的问题

    如果你和我一样对于Node.js是个小白,安装好后你便迫不及待的想要试一把了,按照所有教程中说的,运行中输入cmd->node,

    \"点击查看原图\"

    然后命令行输出Hello world!看到这两个单词,一种幸福之感油然而生。我们还会在cmd中查看Node.js的版本和帮助等等。但总不能总是命令行输入吧,我们想让它像其他服务器端语言一样能够运行文件。

    很多书上都只说,写个hello.js文件,然后用node.js平台运行它就可以了。可是。。。hello.js应该放在哪个目录下呢?

    我们先让它和Node.exe放在一起试一下。然后cmd->node hello.js,运行(很多介绍中都这么写的),

    但显示:

    \"点击查看原图\"

    Error:Cannot find module \'C:UsersAdministratorhello.js\',

    你似乎看出来了,原来运行目录在“\'C:UsersAdministrator”目录下,于是你拷贝一个hello.js在这个目录下重新运行,‘Hello world!’,果真成功了!但如果你想运行Nodejs安装目录下的文件怎么办?

    其实,是要指定到安装目录下再运行node hello.js才对,cmd>cd C:Program Filesnodejs>node hello.js,

    \"点击查看原图\"

    每次都输入这么多定位到安装目录肯定很麻烦呀,所以你可以把nodejs安装目录拷贝到其它盘中(比如我的,E:nodejs)

    然后输入cmd>E:>cd nodejs>node hello.js就可以了,是不是比上面简介多了!你也可以运行你的server.js文件来本地浏览器访问。

    \"点击查看原图\"\"点击查看原图\"

    \"点击查看原图\"

    于是,你就可以开始Node.js的学习了。

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5261, 'csharp-split-string-into-an-array-of-int', '将字符串分割成int数组', '2014-07-15 14:54:20', '2019-03-25 21:29:22', '
    \r\n
    \r\n
      \r\n
    1. #region 将字符串分割成int数组
    2. \r\n
    3.       /// <summary>
    4. \r\n
    5.       ///
    6. \r\n
    7.       /// </summary>
    8. \r\n
    9.       /// <param name=\"str\">字符串</param>
    10. \r\n
    11.       /// <param name=\"split\">分割符</param>
    12. \r\n
    13.       public static int[] StringToIntArray(string str, char split)
    14. \r\n
    15.       {
    16. \r\n
    17.           string input = str.Replace(\",\", \",\").Trim();
    18. \r\n
    19.           string[] str_ids = input.Split(new string[] { \",\" }, StringSplitOptions.RemoveEmptyEntries);
    20. \r\n
    21.           int[] aids = new int[str_ids.Length];
    22. \r\n
    23.           for (int i = 0; i < str_ids.Length; i++)
    24. \r\n
    25.           {
    26. \r\n
    27.               aids[i] = int.Parse(str_ids[i].ToString());
    28. \r\n
    29.           }
    30. \r\n
    31.           return aids;
    32. \r\n
    33.       }
    34. \r\n
    35. \r\n
    36.       #endregion
    37. \r\n
    \r\n
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5282, '20140726202930', '20140726202930', '2014-07-26 12:29:31', '2019-03-25 21:29:22', '重新开发完成。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5283, '20140726204437', '20140726204437', '2014-07-26 12:44:38', '2019-03-25 21:29:22', '8月2号去北京。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5299, 't4-template-engine-note-001-syntax', 'T4模板引擎学习笔记001:语法', '2014-07-31 02:20:22', '2019-03-25 21:29:22', '

    【版权声明:本文为特维博客原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

    含义

    T4,即4个T开头的英文字母组合:Text Template Transformation Toolkit

    T4文本模板,即一种自定义规则的代码生成器。

    根据业务模型可生成任何形式文本文件供程序调用的字符串。(模型以适合于应用程序域的形式包含信息,并且可以在应用程序的生存期更改)

    VS本身只提供一套基于T4引擎的代码生成的执行环境,由下面程序集构成:

    Microsoft.VisualStudio.TextTemplating.10.0.dll

    Microsoft.VisualStudio.TextTemplating.Interfaces.10.0.dll

    Microsoft.VisualStudio.TextTemplating.Modeling.10.0.dll

    Microsoft.VisualStudio.TextTemplating.VSHost.10.0.dll

    语法

    T4的语法与ASP.NET的方式比较类似。主要包括指令块文本块控制块

    指令块

    指令块 - 向文本模板化引擎提供关于如何生成转换代码和输出文件的一般指令。

    6个指令

    <#@ template #>、<#@ parameter#>、<#@ assembly #>、<#@ import #>、<#@ include #>、<#@ output #>

    其中, output 和 assembly 只能用在设计时模板。

    T4 模板指令

    <#@ template [language="C#"] [hostspecific="true"] [debug="true"] [culture="code"] [inherits="templateBaseClass"] [compilerOptions="options"] #>

    这里只说明下 inherits 属性,其余属性在本文更合适的地方有进行说明。

    inherits

    指定模板的程序代码继承自另一个类,该基类可以是由其他模板生成。

    1) 运行时(预处理过的)文本模板中的继承

    如果不指定 inherits 特性,则会从您的文本模板生成基类和派生类。指定 inherits 特性时,仅生成派生类。

    2) 设计时文本模板中的继承

    设计时模板会生成任何类型的“文本文件”,此文件将组成 Visual Studio 项目的一部分。T4 模板引擎首先要将模板转换为中间程序代码文件,中间代码文件将写入您的 %TEMP% (环境变量) 目录。默认该生成的中间代码继承自 Microsoft.VisualStudio.TextTemplating.TextTransformation 类,但你也可根据需求使用 inherits 特性指定派生于 TextTransformation 类的任何基类。

    模板引擎生成转换类更详细的请参考本文后面的 何时编译,编译过程节。

    T4 参数指令

    <#@ parameter type="Full.TypeName" name="ParameterName" #>

    在 Visual Studio 文本模板中,parameter 指令声明模板代码中从自外部上下文传入的值初始化的属性。可以声明任何远程类型的参数。也就是说,类型必须使用SerializableAttribute进行声明,或者必须从MarshalByRefObject派生。这样可以将参数值传递到在其中处理模板的AppDomain中。

    如何使用及内部运作机制请查看我的另一篇文章 《(译)理解 T4 模板:<#@ parameter #> 指令》

    T4 导入指令

    <#@ import namespace="namespace" #>

    T4 包含指令

    <#@ include file="filePath" #>

    a) 为了增加代码的可维护性,将公用函数做为类功能块(<#+ 类功能控制块 #>)存放在单独的文件中,该文件可以被 <#@include#> 到一个或多个模板文件中。

    b) 对于包含文件,文件扩展名使用 .ttinclude可读性更好。(以区分后缀为 .tt的运行时或设计时文本模板)

    T4 输出指令

    <#@ output extension=".fileNameExtension" [encoding="encoding"] #>

    运行时(预处理)文本模板中不需要 output 指令。应用程序通过调用TextTransform() 来获取已生成的字符串。

    T4 程序集指令

    <#@ assembly name="[assembly strong name|assembly file name]" #>

    在预处理文本模板中,assembly 指令无效。改为在 Visual Studio 项目中直接“添加引用”。

    程序集名称应为以下各项之一:

    1. GAC 中程序集的强名称,例如 System.Xml.dll。还可以使用长名称,例如 name="System.Xml, Version=4.0.0.0, Culture=neutral,PublicKeyToken=b77……"。

    2. 程序集的绝对路径

    可以使用 $(variableName) 语法引用 Visual Studio 或MSBuild变量(如 $(SolutionDir)),以及使用 %VariableName% 来引用环境变量。

    另,给出一些常用的 【生成命令和属性的宏】

    $(ConfigurationName)

    当前项目配置的名称(如“Debug”)。

    $(PlatformName)

    当前项目平台的名称(如“Win32”)。

    $(ProjectName)

    项目的基本名称。

    $(TargetDir)

    生成的主输出文件的目录(定义为驱动器 + 路径);包括尾部的反斜杠“”。

    $(TargetName)

    生成的主输出文件的基本名称。

    $(FrameworkDir)

    安装 .NET Framework 的目录。

    $(FrameworkVersion)

    Visual Studio 使用的 .NET Framework 版本。

    $(WebDeployPath)

    从 Web 部署根到项目输出所属于的位置的相对路径。返回与RelativePath相同的值。

    $(WebDeployRoot)

    指向<localhost>位置的绝对路径。例如,c:inetpubwwwroot。

    文本块

    文本块 - 直接复制到输出的内容。

    控制块

    控制块 - 向文本插入可变值并控制文本的条件或重复部件的程序代码,不能在控制块中嵌套控制块。

    有三种类型的控制块,根据其左括号对它们进行区分:

    1. <# 标准控制块 #> 可以包含语句。

    2. <#= 表达式控制块 #> 将一个可以计算为字符串的表达式括起来,用于提供要写入“输出”文件的字符串的代码。

    3. <#+ 类功能控制块 #> 可以使用类功能控制块向文本模板添加方法、属性、字段甚至是嵌套类。必须作为文件中的最后一个块显示,或者用<#@ include #>引入外部文件。

    注意:

    1) 始终使用 {...}花括号来包含内嵌的嵌套语句,否则会报错。(哪怕花括号中只有一句代码)

    2) 控制块不能互相嵌套。必须先终止之前的控制块,然后才能打开另一个。

    设计时模板和运行时模板

    T4文本模板分为:设计时模板和运行时模板

    添加模板

    设计时模板(文本模板)

    优势:当需求变化时,可以根据业务需求调整模型(输入),按照指定规则将“模型”生成任何类型的“文本文件”,例如:网页、资源文件或任\r\n何语言的程序源代码。(模型:是描述应用程序特定方面的数据源。它可以是任何形式、任何类型的文件或数据库。如:数据库、配置文件、UML 模型、DSL 模型或其他源)

    a) VS中新建文件——常规——文本模板。(如图)

    \"image\"

    该模板文件中已包含下列指令:

    <#@ template debug="false" hostspecific="false" language="C#" #>

    <#@ output extension=".txt" #>

    b) 或则,添加“纯文本文件”并设置下图属性,加入相关指令。(后缀推荐改为标准的 *.tt)

    设计时模板: TextTemplatingFileGenerator

    \"image\"

    运行时模板(已预处理的文本模板)

    优势:当需求变化时,可以根据业务需求调整模型(输入),在运行时按照指定规则将“模型”生成为“文本字符串”。

    1. VS中新建文件——常规——已预处理的文本模板。

    该模板文件包含指令:<#@ template language="C#" #>

    2. 或则,添加“纯文本文件”并设置相应属性,加入相关指令。

    运行时模板:TextTemplatingFilePreprocessor

    何时编译,编译过程

    1. 何时编译

    在下列任何一种情况下,将执行模板,同时生成附属文件,生成的文件将作为项目的一部分编译。(属性框----生成操作:编译)

    1) 编辑模板(模板有异动且没有被保存),当前编辑模板失去焦点。

    2) 保存模板。

    3) 在“解决方案资源管理器”工具栏中单击“转换所有模板”。转换解决方案中的所有模板。

    \"image\"

    4) 右击“解决方案资源管理器”中的一个或多个模板文件,然后选择“运行自定义工具”。

    2. 编译过程

    设计时模板

    1) 文本模板转换引擎将“文本模板”转换为可执行的cs代码——“转换类”。转换类(*.cs)存于临时目录下。(临时目录在“环境变量”中设置:右键“我的电脑”—“属性”—“高级系统设置”—“高级”选项卡中“环境变量”—TEMP变量)

    命名空间:Microsoft.VisualStudio.TextTemplating + 随机码

    基类:Microsoft.VisualStudio.TextTemplating.TextTransformation

    类名:GeneratedTextTransformation

    \"image\"

    2) 引擎编译生成的“转换类”生成dll,dll存于临时目录下。具体是哪个dll可以在模板的“调试环境”下使用System.Reflection.Assembly.GetExecutingAssembly();获取。

    3) 执行已编译的转换类,生成“文件”。新文件会在“解决方案资源管理器”中出现在文本模板文件下。

    运行时模板

    1) 运行时模板没有<#@ output #>指令,文本模板引擎将“运行时模板”直接编译为cs文件,作为项目的一部分编译。新文件会在“解决方案资源管理器”中出现在文本模板文件下。

    命名空间:默认为所属程序集的命名空间

    基类:模板文件名 + Base

    类名:模板文件名(PreTextTemplateTest.tt)——注意是“分部类”

    \"image\"

    2) 生成的代码文件随着项目一起编译,并可在应用程序中通过调用生成类中的TransformText() 方法输出“文本字符串”。

    另外,若要在特定命名空间中放置模板转换生成的类,需设置模板文件的“自定义工具命名空间”属性。

    3. 注意事项

    1) 控制块使用陷进

    TransformText() 方法是由模板引擎将模板中的所有“控制块”代码(包括“包含的模板”)组合生成。所以在使用控制块时应注意以下几点:

    a) 语言:只能使用一种语言。

    b) 局部变量:确保局部变量的名称不会冲突。

    2) 文本模板在单独的AppDomain中运行

    请注意,文本模板在与主应用程序分开的AppDomain中运行。在大多数情况下这并不重要,但在某些复杂的情况下您可能会发现一些限制。例如,如果要从单独的服务将数据传入模板或从中传出数据,则该服务必须提供可序列化的 API。

    (四)技巧

    l 快速编写模板

    以生成文件为原型,然后逐步插入用于改变结果的控制块。

    l T4文本模板的断点调试

    1. 注册表:设置DbgJITDebugLaunchSetting值为 2。

    (x86系统): HKEY_LOCAL_MACHINESOFTWAREMicrosoft.NETFramework

    (x64 系统): HKEY_LOCAL_MACHINESOFTWAREWow6432NodeMicrosoft.NETFramework

    2. 为template指令添加debug="true"特性:<#@ template debug="true"#>

    3. 命令:

    <# System.Diagnostics.Debugger.Launch();#> 在模板执行到特定点启动调试器。如果用Debugger.Break()启动调试器在调试完后会导致 VS 奔溃。

    <#System.Diagnostics.Debugger.Break();#> 启动调试器后,使用此命令在后续特定点处再次进入调试模式,相当于断点。

    使用方法:必须使用“Debugger.Launch()”命令启动调试器(如下图,启动新实例或使用已存在的VS附加。注意,若此处点击取消则将关闭当前IDE),调试完后可以不用中断调试,不影响模板编辑,当再次编译模板时如果存在“Debugger.Break()”命令则自动进入调试模式。

    \"123\"

    l 向模板传递参数的两种方法

    1. 使用 <#@ parameter#> 指令引入参数,由模板引擎生成属性访问代码。详细请看 《(译)理解 T4 模板:<#@ parameter #> 指令》

    2. 在构造函数中传递参数。只适用于运行时模板,此种模板生成的代码以分部类的形式编写。可以在项目的另一个文件中创建同一个类的其他部分,该文件可以包含一个带参数的构造函数、若干属性和函数,在调用 TransformText() 实例方法前进行初始化。

    l 使用模板继承共享内容

    可以通过编写基类模板(可以是抽象模板)在文本模板之间共享内容。使用<@#template#> 指令的 inherits 特性指定基类。

    l 运行时调用设计时模板返回字符串

    调用 Microsoft.VisualStudio.TextTemplating.Engine 的 ProcessTemplate 方法。

    publicstring ProcessTemplate(

    string content,

    I\r\nTextTemplatingEngineHost host

    )

    content 参数指定文本模板的内容,eg: 使用System.IO.File.ReadAllText(Path) 进行读取

    host 参数指定的宿主,必须是实现 ITextTemplatingEngineHost 的类。这是由模板引擎回调的。宿主必须能记录错误、解析对程序集和包含文件的引用、提供可在其中执行模板的应用程序域并为每条指令调用相应的处理器。

    演练:创建自定义文本模板宿主

    (五)常用方法

    n 模板基类提供的方法

    设计时模板继承TextTransformation抽象类

    \"image\"

    运行时模板默认继承自动生成的基类

    \"image\"

    1. Write() 和WriteLine() 方法

    写入目的输出文本的三种方式:

    a) 文本块

    b) 表达式控制块: <#= 变量 #>

    c) 标准控制块: <# Write() | WriteLine() #>,因为控制块不能嵌套,所以此种方式比<#= 变量 #>书写更优雅。

    2. 输出文本缩进设置

    可以使用缩进方法设置文本模板输出的格式。

    a) PushIndent(string indent) 添加指定格式,内部会将字符长度加入到缓存变量indentLengths列表(List<int>)。

    b) PopIndent() 以“堆栈(先进后出)”形式移除格式,内部按indentLengths列表中存的字符长度进行移除。

    c) ClearIndent() 删除所有缩进。

    注意:格式用完后要注意清除,否则可能出现模板中的空行会生成 Write(“rn”) 中间代码,最终造成将缩进的格式错误输出到了目的文件。

    Eg:

    \"image\"

    3. 错误报告

    若要在 Visual Studio 错误窗口中放置错误消息和警告消息,可以使用以下方法:

    <# this.Error("An error message"); #>

    <# Warning("A warning message"); #>

    n 使用执行模板的主机(例如 Visual Studio)公开的方法和属性。这适用于常规文本模板,而不是预处理过的文本模板。

    首先,给 template 指令添加hostspecific="true" 特性,以便使用this.Host对象。

    (Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost)接口提供方法

    \"image\"

    1. 使用this.Host.ResolvePath()从相对路径名打开文件

    2. 使用LogErrors() 显示错误消息,如下图:

    \"image\"

    3. 使用 Visual Studio 中提供的服务(加载EnvDTE.dll )

    EnvDTE是組件包裝 COM 程式庫,其中包含了 Visual Studio 核心 Automation 的物件及成員。

    引入 EnvDTE.dll 组件后应按下图“属性”进行设置:

    \"image\"

    示例:

    <#@ assembly name="EnvDTE" #>

    <#

    IServiceProvider serviceProvider = (IServiceProvider)this.Host;

    EnvDTE.DTEdte = (EnvDTE.DTE) serviceProvider.GetService(typeof(EnvDTE.DTE));

    dte.Solution.SaveAs("C:\\backup_Solution");

    #>

    相关文章推荐:

    《T4常用技巧》简洁的介绍了T4中几个常用技巧的使用方式

    T4 模板 : 一种提升ASP.NET MVC开发速度方法

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5305, 'complete-sql-select-statement-execution-order', 'SQL Select语句完整的执行顺序', '2014-07-31 07:46:27', '2019-03-25 21:29:22', '

    【版权声明:本文为特维博客原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

    SQL Select语句完整的执行顺序:

    1、from子句组装来自不同数据源的数据;

    2、where子句基于指定的条件对记录行进行筛选;

    3、group by子句将数据划分为多个分组

    4、使用聚集函数进行计算;

    5、使用having子句筛选分组;

    6、计算所有的表达式;

    7、使用order by对结果集进行排序。

    8、select 集合输出。

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5307, '20140801222105', '20140801222105', '2014-08-01 14:21:07', '2019-03-25 21:29:22', '简单 实用 清爽 才是软件的本质。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5308, '20140802082833', '20140802082833', '2014-08-02 00:28:34', '2019-03-25 21:29:22', '到北京了 悲剧 大神屏幕坏了', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5311, 'turn-nodejs-study-notes-003-small-scale-chopper', 'Nodejs学习笔记003:小试牛刀', '2014-08-03 02:47:26', '2019-03-25 21:29:22', '测试', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5314, '20140804110158', '20140804110158', '2014-08-04 03:03:01', '2019-03-25 21:29:22', '回去之后,晚上坚决不加班了。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5315, '20140808153129', '20140808153129', '2014-08-08 07:31:26', '2019-03-25 21:29:22', 'linux重启mysql:\r\nservice mysqld restart ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5317, 'books-must-be-read-by-coder', '程序员必读书籍推荐', '2014-08-09 02:47:51', '2019-03-25 21:29:22', '\"hard-book-published_-800x800\"\r\n\r\nNo 1\r\n\r\n《算法导论》\r\n\r\n阅读心得:更新中。。。\r\n\r\nNo 2\r\n\r\n《计算机程序设计艺术》\r\n\r\n阅读心得:更新中。。。\r\n\r\nNo 3\r\n\r\n《程序员编程艺术:面试和算法心得》\r\n\r\nNo 4\r\n\r\n《IT企业必读的200个.NET面试题》\r\n\r\n阅读心得:更新中。。。\r\n\r\n ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5320, '20140809143033', '20140809143033', '2014-08-09 06:30:33', '2019-03-25 21:29:22', '2', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5321, '20140810074522', '20140810074522', '2014-08-09 23:45:21', '2019-03-25 21:29:22', '3', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5322, 'android-learning-notes-004-android-process-life-cycle', 'Android学习笔记004: Android 进程生命周期 Process Lifecycle', '2014-08-10 05:38:13', '2019-03-25 21:29:22', '进程的生命周期\r\n  Android系统会尽力保持应用的进程,但是有时为了给新的进程和更重要的进程回收一些内存空间,它会移除一些旧的进程。\r\n\r\n  为了决定哪些进程留下,哪些进程被杀死,系统根据在进程中在运行的组件及组件的状态,为每一个进程分配了一个优先级等级。\r\n\r\n  优先级最低的进程首先被杀死。\r\n\r\n  这个进程重要性的层次结构有五个等级,下面就列出这五种进程,按照重要性来排列,最重要的放在最前。\r\n\r\n\r\n\r\n一.前台进程 Foreground process\r\n  前台进程是用户当前做的事所必须的进程,如果满足下面各种情况中的一种,一个进程被认为是在前台:\r\n\r\n  1.进程持有一个正在与用户交互的Activity(Activity正处于onResume()的状态)。\r\n\r\n  2.进程持有一个Service,这个Service和用户正在交互的Activity绑定。\r\n\r\n  3.进程持有一个Service,这个Service是在前台运行的,即它调用了 startForeground()。\r\n\r\n  4.进程持有一个Service,这个Service正在执行它的生命周期回调函数(onCreate(), onStart(), or onDestroy())。\r\n\r\n  5.进程持有一个BroadcastReceiver,这个BroadcastReceiver正在执行它的 onReceive() 方法。\r\n\r\n  杀死前台进程需要用户交互,因为前台进程的优先级是最高的。\r\n\r\n\r\n\r\n二.可见进程 Visible process\r\n  如果一个进程不含有任何前台的组件,但是仍然影响着用户在屏幕上可以看到的内容,就是可见进程。\r\n\r\n  可见进程满足下列情况之一:\r\n\r\n  1.进程持有一个Activity,这个Activity不在前台,但是仍然被用户可见(处于onPause()调用后又没有调用onStop()的状态)。\r\n\r\n  这种情况发生在,比如,前台的activity打开了一个对话框,这样activity就会在其后可见。\r\n\r\n  2.进程持有一个Service,这个Service和一个可见的(或者前台的)Activity绑定。\r\n\r\n  可见的进程也被认为是很重要的,一般不会被销毁,除非是为了保证所有前台进程的运行而不得不杀死可见进程的时候。\r\n\r\n\r\n\r\n三.服务进程 Service process\r\n  如果一个进程中运行着一个service,这个service是通过 startService() 开启的,并且不属于上面两种较高优先级的情况,这个进程就是一个服务进程。\r\n\r\n  尽管服务进程没有和用户可以看到的东西绑定,但是它们一般在做的事情是用户关心的,比如后台播放音乐,后台下载数据等。\r\n\r\n\r\n\r\n四.后台进程 Background process\r\n  如果进程不属于上面三种情况,但是进程持有一个用户不可见的activity(activity的onStop()被调用,但是onDestroy()没有调用的状态),就认为进程是一个后台进程。\r\n\r\n  后台进程不直接影响用户体验,系统会为了前台进程、可见进程、服务进程而任意杀死后台进程。\r\n\r\n  通常会有很多个后台进程存在,它们会被保存在一个LRU (least recently used)列表中,这样就可以确保用户最近使用的activity最后被销毁,即最先销毁时间最远的activity。\r\n\r\n\r\n\r\n五.空进程\r\n  如果一个进程不包含任何活跃的应用组件,则认为是空进程。\r\n\r\n  保存这种进程的唯一理由是为了缓存的需要,为了加快下次要启动这个进程中的组件时的启动时间。\r\n\r\n  系统为了平衡进程缓存和底层内核缓存的资源,经常会杀死空进程。\r\n\r\n\r\n\r\n相关说明\r\n  1.Android会尽可能地把进程放在高的优先级。\r\n\r\n  比如,一个进程拥有一个可见状态的activity和一个service,这个进程会被认为是可见进程,而不是服务进程。\r\n\r\n  2.一个进程的等级有可能会因为其他进程的依赖而提高,一个进程服务于另一个进程,则它的优先级不会比它服务的进程优先级低。\r\n\r\n  比如,A进程中的一个content provider向B进程中的一个客户提供服务,或A进程中的一个service被绑定在B进程中的一个组件上,则A进程的优先级至少和B进程的优先级一样高。\r\n\r\n  3.因为服务进程的优先级比后台进程的优先级高,所以对于一个需要启动一个长时间操作的activity来说,开启一个service比创建一个工作线程的方法更好,尤其是对于操作将很可能超出activity的持续时间时。\r\n\r\n  比如要上传一个图片文件,应该开启一个service来进行上传工作,这样在用户离开activity时工作仍在进行。使用service将会保证操作至少有服务进程的优先级。\r\n\r\n\r\n\r\n参考资料\r\n  Sandy Zhang Android深入浅出 视频教程——进程生命周期。\r\n\r\n  API Guides: Processes and Threads\r\n\r\n  http://developer.android.com/guide/components/processes-and-threads.html', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5325, 'asp-net-mvc4-study-notes-004-asp-net-mvc-dependency-injection', 'Asp .Net Mvc4学习笔记010:ASP.NET MVC 的依赖注入', '2014-08-12 04:46:03', '2019-03-25 21:29:22', 'http://www.cnblogs.com/cnmaxu/archive/2010/10/13/1849972.html\r\n参考代码', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5331, '20140812185841', '20140812185841', '2014-08-12 10:58:40', '2019-03-25 21:29:22', '当Shell遇上了NodeJS\r\nhttp://www.infoq.com/cn/articles/yph-shell-meet-nodejs', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5332, '20140812185906', '20140812185906', '2014-08-12 10:59:05', '2019-03-25 21:29:22', '-4', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5333, 'programmer-skills-that-must-be-obtained', '程序员必备技能', '2014-08-13 03:22:11', '2019-03-25 21:29:22', '
      \"01300000291746125109739737755\"1 css,js,html
      2 一门后端编程语言(c,c++,java,c#,php,python,ruby,nodejs)
      3 http协议
      4 操作系统原理(pv操作 生产者消费者 多进程 死锁 文件设备管理等)
      5 算法与数据结构(常用结构 线性表 树 图 常用算法 排序 递归 分治法 贪心法等)
      6 一种数据库(access,sql server,mysql,oracle,db2,postdegree,sqlite) 表,视图,存储过程,事务,索引,函数,备份还原
      7 缓存技术
      8 CDN内容分发网络
      9 负载均衡
      10 常用项目架构 如mvc mvp 模版引擎 依赖注入(控制反转) aop面向切面编程等
      11 设计模式
      12 事件驱动,异步编程
      13 一种http服务器(tomcat iis apache ngnix)
      14 一种测试方法 测试驱动 junit nunit mstest
      15 一种并发测试方法 loadrunner
      16 至少了解一种成熟软件架构 blog bbs shop cms erp oa crm boss17 一款熟练操作的操作系统linux,unix,windows(awk,ps,netstat,crontab,free,kill,lsof...)
      18 一款熟练的IDE开发securecrt(vim,emacs),putty,vs,eclipse
      19 一款熟练操作的调试工gdb, vs, eclipse
      20 一款熟悉的NOSQL(redis,memcached,mongodb,hbase,neo4j,db4o,basex)
      21 一款熟悉的关系数据库部署(分表,分库,分片,表锁,行锁,主从,多主同步,集群,负载均衡)
      22 一种分布式缓存思维(一致性hash,求余hash...)
      23 一些集群管理部署经验
      24 一种异步思维-消息队列处理(rabbitmq,activemq)
      25 一些硬件处理的经验(10W并发会占用多少内存,需要多少机器负载,1e条数据需多大SSD)
      26 一些加密思维(散列,对称,非对称)
      27 NLite 框架旨在提供一个轻量级的组件库-DI(Data Item数据项),Aop,MessageBus, OO Mapper,国际化,数据校验,日志,异常管理,多线程等
      ...
      n 学习能力
      n+1 实践能力
      n+2 终身学习能力
      n+3 团队合作意识
      n+4 创新思维方式
      仅以此文共勉。
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5338, 'centos-mono-nginx-deployment-mvc4webapi', 'CentOS Mono Nginx 部署 MVC4+WebApi', '2014-08-13 04:27:08', '2019-03-25 21:29:22', '

    http://www.cnblogs.com/acles/archive/2013/09/11/3313716.html

     

    http://www.linuxdot.net/bbsfile-3784

     

    cd /tmp
    wget http://security.ivannet.com/linux/shell/centos6.x_mono_jexus_opt.sh
    chmod +x centos6.x_mono_jexus_opt.sh
    ./centos6.x_mono_jexus_opt.sh

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5342, '20140814195323', '20140814195323', '2014-08-14 11:53:28', '2019-03-25 21:29:22', '-1', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5343, '20140816093028', '20140816093028', '2014-08-16 01:30:30', '2019-03-25 21:29:22', '终于回来了。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5347, 'linq-to-entities%e5%ad%a6%e4%b9%a0%e7%ac%94%e8%ae%b0010%ef%bc%9a%e4%b8%80%e4%b8%aaiqueryable%e5%8c%bf%e5%90%8d%e5%af%b9%e8%b1%a1%e5%8d%b0%e5%8f%91%e7%9a%84%e6%80%9d%e8%80%83', 'LINQ to Entities学习笔记010:一个IQueryable匿名对象印发的思考', '2014-08-20 03:34:05', '2019-03-25 21:29:22', '

    参见

    http://bbs.csdn.net/topics/390865900

    http://q.cnblogs.com/q/65140/

     

    我的解决方案:

    1. var compUsers = CompanyUser();  
    2.                         foreach (var compUser in compUsers)  
    3.                         {  
    4.                             var aaa = compUser.CompanyId;  
    5.                         }  
    6.                         ResponseMessage rmsg=new ResponseMessage();  
    7.  
    8.  
    9.  
    10.  
    11.  
    12. //            var compUsers = CompanyUser();  
    13. //            var compUser = compUsers.FirstOrDefault();  
    14. ////            foreach (var compUser in compUsers)  
    15. ////            {  
    16. //                var aaa = compUser.GetProperty("CompanyId");  
    17. ////            }  
    18. //            ResponseMessage rmsg=new ResponseMessage(); 
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5350, 'js%e8%8e%b7%e5%8f%96ip%e5%9c%b0%e5%9d%80', 'JS获取IP地址', '2014-08-21 06:42:54', '2019-03-25 21:29:22', '

    使用的搜狐接口
    <script src="http://pv.sohu.com/cityjson?ie=utf-8"></script>
    <script type="text/javascript">
    document.write(returnCitySN["cip"]+\',\'+returnCitySN["cname"])
    </script>

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5352, 'serverversion-exception-invalid-operation-the-connection-is-closed-solutions', 'ServerVersion异常,无效操作。连接被关闭。解决方案', '2014-08-21 09:37:11', '2019-03-25 21:29:22', '

    【版权声明:本文为特维博客原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

    问题引入

    问题在于:State Closed System.Data.ConnectionState

    解决方案

    连接没有open().
    在try中加入
    if (oleDbConnection1.State != ConnectionState.Open)
        oleDbConnection1.Open();
    加上
    finally
    {
        if (oleDbConnection1.State != ConnectionState.Close)
        {
            oleDbConnection1.Close();
        }
    }

     

    详见http://bbs.csdn.net/topics/90347542

     

    1. /// <summary>  
    2.         /// 添加实体  
    3.         /// </summary>  
    4.         /// <param name="sysCompany"></param>  
    5.         /// <param name="sysUser"></param>  
    6.         public bool InsertEntities(TSysCompany sysCompany, TSysUser sysUser)  
    7.         {  
    8.             using (teaCRMDBContext db = new teaCRMDBContext())  
    9.             {  
    10.                 if (db.Connection.State != ConnectionState.Open)  
    11.                 {  
    12.                     db.Connection.Open();  
    13.                 }  
    14.                 var tran = db.Connection.BeginTransaction();  
    15.                 try 
    16.                 {  
    17.                     db.TSysCompanies.Insert(sysCompany);  
    18.                     db.TSysUsers.Insert(sysUser);  
    19.                     tran.Commit();  
    20.                     return true;  
    21.                 }  
    22.                 catch (Exception ex)  
    23.                 {  
    24.                     tran.Rollback();  
    25.                     throw new Exception(ex.Message);  
    26.                     return false;  
    27.                       
    28.                 }  
    29.                 finally 
    30.                 {  
    31.                     if (db.Connection.State != ConnectionState.Closed)  
    32.                     {  
    33.                         db.Connection.Close();  
    34.                     }  
    35.                 }  
    36.             }  
    37.         } 
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5357, 'csharp-to-delete-list-of-all-null-values', '删除List里面的所有空值', '2014-08-22 09:26:27', '2019-03-25 21:29:22', '
    \r\n
    \r\n
      \r\n
    1. #region  删除list中所有为空的元素 
    2. \r\n
    3. \r\n
    4.        /// <summary> 
    5. \r\n
    6.        ///删除list中所有为空的元素 
    7. \r\n
    8.        ///删除为空的操作方式非常复杂,因为你每一次删除一个元素之后, 
    9. \r\n
    10.        ///当前的list的大小就会变化,但是反过来想,如果只是获取它不为 
    11. \r\n
    12.        ///空的元素则不需要考虑它的size大小的变化,而且比较简单。 
    13. \r\n
    14.        ///
    15. \r\n
    16.        /// </summary>
    17. \r\n
    18.        /// <param name=\"list\"></param>
    19. \r\n
    20.        /// <returns></returns>
    21. \r\n
    22.        public static List<string> RemoveEmptyList(List<string> list)
    23. \r\n
    24.        {
    25. \r\n
    26.            List<string> list1 = new List<string>();
    27. \r\n
    28. \r\n
    29.            if (list == null || list.Count <= 0)
    30. \r\n
    31.            {
    32. \r\n
    33.                return null;
    34. \r\n
    35.            }
    36. \r\n
    37.            //循环第一层  
    38. \r\n
    39.            for (int i = 0; i < list.Count; i++)
    40. \r\n
    41.            {
    42. \r\n
    43.                //进入每一个list  
    44. \r\n
    45.                string listi = list[i];
    46. \r\n
    47.                if (!String.IsNullOrEmpty(listi))
    48. \r\n
    49.                {
    50. \r\n
    51.                    list1.Add(listi);
    52. \r\n
    53.                }
    54. \r\n
    55.            }
    56. \r\n
    57. \r\n
    58.            return list1;
    59. \r\n
    60.        }
    61. \r\n
    62. \r\n
    63.        #endregion
    64. \r\n
    \r\n
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5360, 'mysql-exceptions-mysqlnontransientconnectionexception-no-operations-allowed-after-statement-closed', 'Mysql异常:MySQLNonTransientConnectionException: No operations allowed after statement closed', '2014-08-22 11:32:57', '2019-03-25 21:29:22', '

    【版权声明:本文为特维博客原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

    MySQLNonTransientConnectionException: No operations allowed after statement closed

        之所以会出现这个异常,是因为Mysql在5以后针对超长时间DB连接做了一个处理,那就是如果一个DB连接在无任何操作情况下过了8个小时后,Mysql会自动把这个连接关闭。所以使用连接池的时候虽然连接对象还在但是链接数据库的时候会一直报这个异常。解决方法很简单在Mysql的官方网站上就可以找到。

    有两个方法,

    第一种是在DB连接字符串后面加一个参数。

    这样的话,如果当前链接因为超时断掉了,那么驱动程序会自动重新连接数据库。

    jdbc:mysql://localhost:3306/makhtutat?autoReconnect=true

    不过Mysql并不建议使用这个方法。因为第一个DB操作失败的后,第二DB成功前如果出现了重新连接的效果。这个失败操作将不会处于一个事务以内,第二DB操作如果成功的话,这个事务将被提交。
    conn.createStatement().execute(\r\n  "UPDATE checking_account SET balance = balance - 1000.00 WHERE customer=\'Smith\'");\r\nconn.createStatement().execute(\r\n  "UPDATE savings_account SET balance = balance + 1000.00 WHERE customer=\'Smith\'");\r\nconn.commit();
    \r\n
    \r\n\r\n

    当然如果出现了重新连接,一些用户变量和临时表的信息也会丢失。

    \r\n\r\n
    另一种方法是Mysql推荐的,需要程序员手动处理异常。
    \r\n\r\n
    \r\n
    \r\n\r\n
      \r\n
    1. public void doBusinessOp() throws SQLException {    
    2. \r\n\r\n
    3.     Connection conn = null;    
    4. \r\n\r\n
    5.     Statement stmt = null;    
    6. \r\n\r\n
    7.     ResultSet rs = null;    
    8. \r\n\r\n
    9.     int retryCount = 5;    
    10. \r\n\r\n
    11.     boolean transactionCompleted = false;    
    12. \r\n\r\n
    13.     do {    
    14. \r\n\r\n
    15.         try {    
    16. \r\n\r\n
    17.             conn = getConnection(); // assume getting this from a    
    18. \r\n\r\n
    19.                                     // javax.sql.DataSource, or the    
    20. \r\n\r\n
    21.                                     // java.sql.DriverManager    
    22. \r\n\r\n
    23.             conn.setAutoCommit(false);    
    24. \r\n\r\n
    25.             retryCount = 0;    
    26. \r\n\r\n
    27.             stmt = conn.createStatement();    
    28. \r\n\r\n
    29.             String query = "SELECT foo FROM bar ORDER BY baz";    
    30. \r\n\r\n
    31.             rs = stmt.executeQuery(query);    
    32. \r\n\r\n
    33.             while (rs.next()) {    
    34. \r\n\r\n
    35.             }    
    36. \r\n\r\n
    37.             all.close()    
    38. \r\n\r\n
    39.             transactionCompleted = true;    
    40. \r\n\r\n
    41.         } catch (SQLException sqlEx) {    
    42. \r\n\r\n
    43.             String sqlState = sqlEx.getSQLState();    
    44. \r\n\r\n
    45.            // 这个08S01就是这个异常的sql状态。单独处理手动重新链接就可以了。    
    46. \r\n\r\n
    47.             if ("08S01".equals(sqlState) || "40001".equals(sqlState))     
    48. \r\n\r\n
    49.                 {                    
    50. \r\n\r\n
    51.                     retryCount--;                
    52. \r\n\r\n
    53.                  } else {                    
    54. \r\n\r\n
    55.                      retryCount = 0;                
    56. \r\n\r\n
    57.                      }            
    58. \r\n\r\n
    59.          } finally {                
    60. \r\n\r\n
    61.                  all close:            
    62. \r\n\r\n
    63.              }        
    64. \r\n\r\n
    65.       } while (!transactionCompleted && (retryCount > 0));}    
    66. \r\n\r\n
    67. \r\n
    \r\n
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5363, '20140824152643', '20140824152643', '2014-08-24 07:26:46', '2019-03-25 21:29:22', 'crm将是我真正用心完成的作品。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5371, '%e3%80%90%e8%bd%ac%e3%80%91%e4%b8%ba%e7%9f%a5%e6%9b%b4%e9%b8%9fwordpress%e5%93%8d%e5%ba%94%e5%bc%8f%e4%b8%bb%e9%a2%98ality%e6%b7%bb%e5%8a%a0%e5%8f%8b%e6%83%85%e9%93%be%e6%8e%a5%e9%a1%b5%e9%9d%a2', '为知更鸟WordPress响应式主题Ality添加友情链接页面', '2014-08-24 10:52:59', '2019-03-25 21:29:22', '

    【版权声明:本文转载自幸福守候,版权归原作者。如需转载,请务必在转载时注明原文地址。】

    WordPress主题自从对知更鸟的HotNews不支持响应式之后,就有点失望了。辗转也更换了几个主题,虽说也是各有特色,但是看到知更鸟发布最新响应式主题Ality之后,还是忍不住换上了新装。由于知更鸟后期会发布相对高级的版本,所以此次Ality版本并没有添加友情链接页面,在此也分享一下自己这位菜鸟摸索为知更鸟响应式主题Ality添加友情链接页面过程。

    友情链接示例:点击

    其实网上的教程一大把,但是需要注意一些方面。一个是不是代码原文输出的,最好谨慎处理,因为有些文章会默认处理代码中的字符,导致代码出错。另一个就是要结合自己的主题,修改相应的模块,使得与自己的主题融为一体。

    1、复制一份你主题的page.php,改名为 page-links.php。

    2、在 page-links.php 找到文章内容输出函数 <?php the_content(); ?>,在其下面加入下面的代码,注意看代码注释:

    <div class="page-links">\r\n	<h1>页内链接</h1>\r\n	<ul>\r\n  	  <?php\r\n  	  $default_ico = get_template_directory_uri().\'/images/links_default.gif\'; //默认 ico 图片位置\r\n 	   $bookmarks = get_bookmarks(\'title_li=&orderby=rand\'); //全部链接随机输出\r\n 	   //如果你要输出某个链接分类的链接,更改一下get_bookmarks参数即可\r\n  	  //如要输出链接分类ID为5的链接 title_li=&categorize=0&category=5&orderby=rand\r\n  	  if ( !empty($bookmarks) ) {\r\n 	       foreach ($bookmarks as $bookmark) {\r\n  	  echo \'<li><img src="\', $bookmark->link_url , \'/favicon.ico" onerror="javascript:this.src=\'\' , $default_ico , \'\'" /><a href="\' , $bookmark->link_url , \'" title="\' , $bookmark->link_description , \'" target="_blank" >\' , $bookmark->link_name , \'</a></li>\';\r\n  	  }\r\n  	  }\r\n  	  ?>\r\n  	</ul>\r\n</div>
    \r\n\r\n

    3、为了好看点,你可以在style.css中给 page-links 这个class定义一下样式,下面是我的主题所用样式,可以参考一下:

    \r\n\r\n
    /**友情链接page-links**/\r\n.page-links{overflow:hidden;margin:0 0 24px;padding:0;}\r\n.page-links h3{border-bottom:1px solid #bfbebe;text-align:center;margin:0;}\r\n.page-links ul{margin:0;padding:5px 0 0 0;}\r\n.page-links ul li{float:left;width:150px;line-height:16px;height:16px;margin:5px 5px 0;padding:0;list-style-type:none;}\r\n.page-links ul li:hover{background:#f2f2f2;}\r\n.page-links ul li img{width:16px;height:16px;margin:0 5px -2px 0;padding:0;border:none;}
    \r\n\r\n

    4、建立一个页面,别名(slug)为 links 即可。

    \r\n\r\n

    以上则是为Wordpress主题添加友情链接页面的统一模板,针对知更鸟的Ality主题,本人在此分享自己的Page-links.php文件,需要自取。

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5385, 'temporarily-disabling-resharper', '临时禁用Resharper', '2014-08-24 12:49:07', '2019-03-26 00:15:12', '

    【版权声明:本文为特维博客原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

    Resharper是一个VisualStudio插件,VS2010利器,能大大提高编程效率,实现了VS没有实现的很多功能,例如代码检查、自动重构、自动生成LINQ语句、编码建议等,个人非常喜欢。但Resharper5,Resharper6经常会导致VS2010崩溃异常退出,这个问题很烦人,只有一个解决办法,那就是临时禁用Resharper。在VS2010 -Tools - Options - Resharper - Suspend即可。如下图:

    \"image_thumb19\"

    附:VS2010常用快捷键(有些是个人自定义的Tools – Options – Environment - Keyboard)

    Ctrl+K,Ctrl+D    格式化代码   
    Ctrl+M,Ctrl+M    折叠/展开选中代码   
    Ctrl+M,Ctrl+O    折叠当前文档代码
    Ctrl+K,Ctrl+K    添加/删除书签   
    Ctrl+K,Ctrl+C    注释   
    Ctrl+K,Ctrl+U    取消注释
    SHIFT + ALT + ENTER            全屏显示
    CTRL + ALT+ Break                停止调试

    F2 关闭搜索结果
    F3 关闭Tab
    F4 全局搜索
    F6 编译
    F7 打开代码
    F8 显示搜索结果
    F9 添加删除断点
    Ctrl+Shift+F9 删除所有断点
    F10 Step
    F11 Setp into
    F12 转到定义

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5389, '%e5%b8%b8%e7%94%a8%e6%ad%a3%e5%88%99%e8%a1%a8%e8%be%be%e5%bc%8f', '常用正则表达式', '2014-08-25 02:59:38', '2019-03-25 21:29:22', '

    不能包含中文

    /.*?[u4E00-u9FFF]+.*/

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5391, '%e5%88%86%e4%ba%ab%e6%88%91%e5%af%b9-asp-net-vnext-%e7%9a%84%e4%b8%80%e4%ba%9b%e6%84%9f%e5%8f%97%ef%bc%8c%e4%b9%9f%e8%ae%b8%e5%a4%9a%e5%b9%b4%e5%9b%9e%e8%bf%87%e5%a4%b4%e7%9c%8b-so-easy%ef%bc%81', '分享我对 ASP.NET vNext 的一些感受,也许多年回过头看 So Easy!', '2014-08-26 01:36:12', '2019-03-25 21:29:22', '

    VS 14 CTP 下载地址:

    • Web 版:http://go.microsoft.com/fwlink/?LinkId=399011
    • ISO 版:http://go.microsoft.com/fwlink/?LinkId=399010

    关于 ASP.NET vNext

    ASP.NET vNext 的发布文章称其为.NET下一代,其实我个人觉得并不准确,ASP.NET vNext 就像其名字一样,应该是 ASP.NET 的下一代版本。ASP.NET vNext 代表着.NET的未来的发展方向,比如说跨平台、开源等,也就是 vNext。关于ASP.NET vNext,园中也有几位大神写过几篇介绍的文章,以下是个人整理关于ASP.NET vNext 的一些特性(更新时间为6月3日):

    • ASP.NET vNext 跨平台。

    .NET未来构想图,对于 ASP.NET vNext 来说,可以看出尤其侧重于云优化-Cloud Optimized,包含高吞吐量、低内存消耗、并行执行和跨平台:

    \"\"

    ASP.NET vNext 成员图:

    \"\"

    从上图可以更直观的看出 ASP.NET vNext 所涵盖的东西,这样的统一管理,带给编程人员好处是很多的,比如:一路由系统、 一个模型绑定系统、 一个筛选器管道等,也可以完美的从 Web Pages 过渡到 MVC。

    .NET vNext 和 .NET vNext -云优化(包含模块)示意图:

    \"\"

    ASP.NET vNext 云优化示意图:

    \"\"

    代码到 Web 服务器示意图,”快速迭代式开发“,即修改代码刷新浏览器,接近实时,也可以实现”云编辑“功能:

    \"\"

    ASP.NET vNext 跨平台示意图:

    \"\"

    ASP.NET vNext 实践

    关于 ASP.NET vNext 的实践,MSDN 已经更新了"Music Store"(音乐商店)项目,感兴趣的朋友可以参考练习下,下面做的 ASP.NET vNext 简单示例,只是个人的学习记录,方面以后自己查看,园友们可以直接略过。

    首先打开 VS 14 CTP,新建 ASP.NET vNext 项目。

    \"\"

    ASP.NET vNext 主要包含三类模板:

    • ASP.NET vNext Web Application:用于创建 Web 应用程序。
    • ASP.NET vNext Class Library:用于创建云优化类库项目。
    • ASP.NET vNext Console Application:用于创建控制台应用程序。

    新建 vNextDemo 项目后,发现目录结构非常简单.

    \"\"

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5393, 'spring-net-learning-note-001-environmental-tie-in-and-hello-world', 'Spring .NET学习笔记001:环境搭配及Hello World', '2014-08-26 02:35:50', '2019-03-25 21:29:22', '

    【版权声明:本文为特维博客原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

    前言

    很久之前都接触了Spring .NET,只是一直没有在项目中使用,今天就开始尝试在新项目里面使用。

    步骤

    1、新建控制台项目

    \"1\"

    2、安装依赖

    在PM Condole输入:Install-Package Spring.Core –Pre

    会自动安装Spring.Core和Common.Logging

    \"2\"

    3、新建App.config,代码如下:

    1. <?xml version="1.0" encoding="utf-8" ?> 
    2. <configuration> 
    3.     <configSections> 
    4.         <sectionGroup name="spring"> 
    5.             <section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/>              
    6.         </sectionGroup> 
    7.     </configSections> 
    8.     <spring> 
    9.         <context> 
    10.             <resource uri="file://spring.xml.config"/> 
    11.         </context> 
    12.     </spring> 
    13. </configuration> 

    4、新建spring.xml.config(这个名字可自定,如需改名,则在App.config的rescource里也需一并修改),代码如下:

    1. <?xml version="1.0" encoding="utf-8" ?> 
    2. <objects xmlns="http://www.springframework.net"> 
    3.     <object id="hello" type="SpringNetDemo.Hello"> 
    4.         <property name="HelloWord" value="Hello!你能看到这个证明你成功了!"/> 
    5.     </object> 
    6. </objects> 

    5、修改项目原来的Program.cs文件:

    1. using System;  
    2. using System.Collections.Generic;  
    3. using System.Text;  
    4. using Spring.Context;  
    5. using Spring.Context.Support;  
    6.  
    7. namespace SpringNetDemo  
    8. {  
    9.     public class Hello  
    10.     {  
    11.         private string helloword;  
    12.  
    13.         public string HelloWord  
    14.         {  
    15.             get { return this.helloword; }  
    16.             set { this.helloword = value; }  
    17.         }  
    18.     }  
    19.     public class Program  
    20.     {  
    21.         static void Main(string[] args)  
    22.         {  
    23.             IApplicationContext context = ContextRegistry.GetContext();  
    24.             Hello hello = (Hello)context.GetObject("hello");  
    25.             Console.Write(hello.HelloWord);  
    26.             Console.Read();  
    27.         }  
    28.     }  

    说明:这里的hello.HelloWord就是Spring.Net通过xml的配置实现注入的。有问题的可以留言。

    注意

    在这里可能会出错,提示Common.Logging版本过低,解决办法是重新安装Common.Logging:

    Install-Package Common.Logging

    \"3\"

    Web项目注意事项

    需要输入:

    Install-Package Spring.Web.Mvc4 –Pre

    \"11\"

    并且Goble.asax还有修改:

    1. using System;  
    2. using System.Collections.Generic;  
    3. using System.Linq;  
    4. using System.Web;  
    5. using System.Web.Http;  
    6. using System.Web.Mvc;  
    7. using System.Web.Routing;  
    8.  
    9. namespace teaCRM.Web  
    10. {  
    11.     // Note: For instructions on enabling IIS6 or IIS7 classic mode,   
    12.     // visit http://go.microsoft.com/?LinkId=9394801  
    13.     //public class MvcApplication : System.Web.HttpApplication  
    14.     public class MvcApplication : Spring.Web.Mvc.SpringMvcApplication  
    15.     {  
    16.         protected void Application_Start()  
    17.         {  
    18.             //注册区域  
    19.             AreaRegistration.RegisterAllAreas();  
    20.             //注册WebApi  
    21.             WebApiConfig.Register(GlobalConfiguration.Configuration);  
    22.             //注册过滤器  
    23.             FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);  
    24.             RouteConfig.RegisterRoutes(RouteTable.Routes);  
    25.             RegisterView(); //注册视图访问规则  
    26.         }  
    27.  
    28.         /// <summary>  
    29.         /// 注册自定义视图  
    30.         /// </summary>  
    31.         pr\r\notected void RegisterView()  
    32.         {  
    33.             ViewEngines.Engines.Clear();  
    34.             ViewEngines.Engines.Add(new MyViewEngine());  
    35.         }  
    36.     }  
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5404, 'c%e4%b8%ad%e5%b7%a7%e7%94%a8%e6%8e%a5%e5%8f%a3%e5%ae%9e%e7%8e%b0%e6%89%a9%e5%b1%95', 'C#中巧用接口实现扩展', '2014-08-26 13:41:33', '2019-03-25 21:29:22', '

    需求

    我有一个是新IA接口的类A,现在我想扩展A类的功能,鉴于某种原因,不能更改IA接口,怎么办?

    我的方案

    定义一个IB接口继承自IA接口,然后定义一个B类实现IB接口并且继承自A类。

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5406, 'tools', '原创工具', '2014-08-31 06:37:24', '2019-03-25 21:29:22', 'http://www.ico.la/', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5417, '%e3%80%90%e5%8e%9f%e3%80%91centos%e8%a7%a3%e5%8e%8brar', 'Centos解压rar', '2014-08-31 11:25:48', '2019-03-25 21:29:22', '

    [root@zebra]# wget http://www.rarsoft.com/rar/rarlinux-4.0.1.tar.gz

    [root@zebra]# tar -zxvf rarlinux-4.0.1.tar.gz
    rar/
    rar/readme.txt
    rar/default.sfx
    rar/whatsnew.txt
    rar/license.txt
    rar/order.htm
    rar/rar
    rar/unrar
    rar/rar_static
    rar/technote.txt
    rar/rarfiles.lst
    rar/makefile
    rar/rar.txt
    [root@zebra]# cd rar

    [root@zebra]# rar bgp-monitor-2.0.rar
    -bash: /usr/local/bin/rar: /lib/ld-linux.so.2: bad ELF interpreter: 没有那个文件或目录

    [root@rar]# cp rar_static /usr/local/bin/rar  
    cp:是否覆盖"/usr/local/bin/rar"? y

    [root@zebra]# rar bgp-monitor-2.0.rar

    RAR 4.01   Copyright (c) 1993-2011 Alexander Roshal   28 May 2011
    Shareware version         Type RAR -? for help

    Extracting from bgp-monitor-2.0.rar

    Creating    bgp-monitor-2.0                                           OK

    。。。

    参考

    1. http://hi.baidu.com/nmxiaoxin/item/7642a139918a95677d034b6a

    2.http://blog.sina.com.cn/s/blog_665acfbf0100vr3p.html

     

     

    先记住两个常用命令吧:

    rar x yhcsh.rar //解压 yhcsh.rar 到当前目录
    rar yhcsh.rar ./yhcsh/  //将 yhcsh 目录打包为 yhcsh.rar

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5421, '20140903175302', '20140903175302', '2014-09-03 09:53:03', '2019-03-25 21:29:22', '多使用jquery $.trim()', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5422, 'jqueryvalidate-poshytip-realise-form-perfect-validation', 'jquery.validate结合poshytip实现表单完美验证', '2014-09-03 12:13:11', '2019-03-25 21:29:22', '

    【版权声明:本文为特维博客原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

    需要引用的js

    1. <script src="/Themes/default/lib/jquery/jquery-1.7.1.min.js" type="text/javascript"></script>  
    2. <!--气泡提示-->
         <script src="/Themes/default/lib/poshytip/jquery.poshytip.min.js" type="text/javascript"></script>
         <link href="/Themes/default/lib/poshytip/tip-yellow/tip-yellow.css" rel="stylesheet"
             type="text/css" />

    3. <!--公共函数-->  
    4.    <script src="/Themes/default/lib/function.js" type="text/javascript"></script>  
    5.  function.js代码:  
    6.  
    7. //============================================  
    8. //formtip===================================  
    9. (function($) {  
    10.     $.fn.formtip = function(message, second, option) {  
    11.         if (second == undefined)  
    12.             second = 3;  
    13.         $(".tip-yellow").remove();  
    14.         try {  
    15.             $(this).poshytip({ className: \'tip-yellow\', content: message, timeOnScreen: second * 1000, showOn: \'none\', alignTo: \'target\', alignX: \'inner-left\', offsetX: 0, offsetY: 5 }).poshytip("show");  
    16.          $(this).focus();//注意,要结合jquery.validate必须放在后面  
    17.         } catch (e) {  
    18.             $(this).blur(function() {  
    19.                  alert(message);  
    20.             });  
    21.              
    22.         }  
    23.     }  
    24. })(jQuery);  
    25. //====================================  
    26.  
    27.  
    28.    <!--表单验证,需要在字段上加上class="required"-->  
    29.    <script src="/Themes/default/lib/validate/jquery.validate.min.js" type="text/javascript"></script>  
    30.    <script src="/Themes/default/lib/validate/messages_cn.js" type="text/javascript"></script>  
    31.    <script src="/Themes/default/lib/validate/jquery.validate.extend.js" type="text/javascript"></script>  
    32.  

    页面使用

    1.   //表单验证  
    2.     $("#form_customer").validate({  
    3.         rules: {  
    4.             cus_name: {  
    5.                 rangelength: [2, 20]  
    6.             },  
    7.             cus_tel: {  
    8.                 remote: {  
    9.                     url: \'/Apps/CRM/LoadData/ValidatePhone/\'  
    10.                     //                    ,data: {  
    11.                     //                        action: function () { return "validate_phone"; }  
    12.                     //                    }  
    13.                 },  
    14.                 con_name: {  
    15.                     rangelength: [2, 20]  
    16.                 }  
    17.             }  
    18.         },  
    19.         messages: {  
    20.             cus_name: {  
    21.                 required: "客户名称不能为空!",  
    22.                 rangelength: "客户名称长度必须在2-20之间" 
    23.             },  
    24.             cus_tel: {  
    25.                 remote: "该电话或手机号码已存在!" 
    26.             },  
    27.             con_name: {  
    28.                 required: "主联系人名称不能为空!",  
    29.                 rangelength: "主联系人名称长度必须在2-20之间" 
    30.             }  
    31.         },  
    32. //        success: function(element) {  
    33. //            var elem = $(element);  
    34. //            elem.poshytip(\'disable\');  
    35. //            elem.poshytip(\'destroy\');  
    36. //        },  
    37.         errorPlacement: function(error, element) {  
    38.             var errorMsg = error[0].innerHTML;  
    39.             var elementName = element[0].name;  
    40.             $("#" + elementName).formtip(errorMsg);  
    41.         }  
    42.     }); 

    演示

    \"20140903201127\"

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5426, 'csharp-using-reflection-in-the-dao-layer-dynamically-change-field-values', 'C#使用反射在Dao层动态改变字段的值', '2014-09-05 03:50:18', '2019-03-25 21:29:22', '

    【版权声明:本文为特维博客原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

    代码1

    1. /// <summary>  
    2. /// 使用LINQ更改客户状态(只更改主表) 2014-09-05 14:58:50 By 唐有炜  
    3. /// </summary>  
    4. /// <param name="fields">要更新的字段</param>  
    5. /// <param name="predicate">条件</param>  
    6. /// <returns></returns>  
    7. public bool UpdateCustomerStatusByLINQ(Dictionary<string, object> fields,  
    8.     Expression<Func<TCusBase, bool>> predicate)  
    9. {  
    10.     var entity = GetEntity(predicate);  
    11.     foreach (var field in fields)  
    12.     {  
    13.         PropertyInfo[] propertyInfos = entity.GetType().GetProperties();  
    14.         foreach (var p in propertyInfos)  
    15.         {  
    16.             if (p.Name == field.Key)  
    17.             {  
    18.                 p.SetValue(entity, field.Value, null); //给对应属性赋值  
    19.             }  
    20.         }  
    21.     }  
    22.     UpadateEntity(entity);  
    23.     return false;  

    代码2

    1. /// <summary>  
    2.     /// 获取指定的单个实体  
    3.     /// 如果不存在则返回null  
    4.     /// 如果存在多个则抛异常  
    5.     /// </summary>  
    6.     /// <param name="predicate">Lamda表达式</param>  
    7.     /// <returns>Entity</returns>  
    8.     public TCusBase GetEntity(Expression<Func<TCusBase, bool>> predicate)  
    9.     {  
    10.         using (teaCRMDBContext db = new teaCRMDBContext())  
    11.         {  
    12.             var model = db.TCusBases.Where<TCusBase>(predicate).SingleOrDefault();  
    13.             return model;  
    14.         }  
    15.     } 

    代码3

    1. /// <summary>  
    2.      /// 修改实体  
    3.      /// </summary>  
    4.      /// <param name="entity">实体对象</param>  
    5.      public bool UpadateEntity(TCusBase entity)  
    6.      {  
    7.          using (teaCRMDBContext db = new teaCRMDBContext())  
    8.          {  
    9.              int rows = db.TCusBases.Update(entity);  
    10.              if (rows > 0)  
    11.              {  
    12.                  return true;  
    13.              }  
    14. \r\n0;            else 
    15.              {  
    16.                  return false;  
    17.              }  
    18.          }  
    19.      } 
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5431, '20140905232500', '20140905232500', '2014-09-05 15:25:01', '2019-03-25 21:29:22', '一个人,最怕的是忘记自己的初衷。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5432, '%e4%bd%bf%e7%94%a8mvc4%e8%87%aa%e5%b8%a6%e7%9a%84%e7%ac%ac%e4%b8%89%e6%96%b9%e8%b4%a6%e6%88%b7%e9%aa%8c%e8%af%81', '使用MVC4自带的第三方账户验证及css js压缩', '2014-09-11 02:15:41', '2019-03-25 21:29:22', '

    Install-Package DotNetOpenAuth.AspNet -Version 4.1.4.12333

    Install-Package Microsoft.AspNet.WebPages.OAuth -Version 2.0.30506

     

     

    安装 bundle

    Install-Package Microsoft.AspNet.Web.Optimization -Version 1.1.0

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5437, 'net-mvc4%e6%80%a7%e8%83%bd%e6%b5%8b%e8%af%95%e5%b7%a5%e5%85%b7', '.NET MVC4性能测试工具', '2014-09-11 07:42:47', '2019-03-25 21:29:22', '

    .NET MVC4性能测试工具

    Install-Package Glimpse.MVC4

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5439, 'mvc-web-api%e6%8e%a5%e5%8f%97post%e5%8f%82%e6%95%b0', 'MVC Web Api接受POST参数', '2014-09-12 02:29:54', '2019-03-25 21:29:22', '

    上搜了一大圈,各种方案都有,但不是太详细,于是跟踪Action中的变量,仔细查看,最后发现了解决方案,下面是代码:

    \"复制代码\"

    1  public void Post([FromBody]string value)\r\n2         {\r\n3             HttpContextBase context = (HttpContextBase)Request.Properties["MS_HttpContext"];//获取传统context\r\n4             HttpRequestBase request = context.Request;//定义传统request对象\r\n5             string name = request.Form["name"];\r\n6\r\n7         }
    \r\n\r\n

    \"复制代码\"

    \r\n\r\n

    WEBAPI中的Request是HttpRequestMessage类型,不能像Web传统那样有querystring和from 方法接收参数,而传统的HttpReqest的基类是HttpReqestBase

    \r\n\r\n

    所以这里我们就直接使用(HttpContextBase)Request.Properties["MS_HttpContext"]

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5441, 'two-nice-sql-page-code', '两段很好的SQL分页代码', '2014-09-12 11:31:45', '2019-03-25 21:29:22', '

    【版权声明:本文为特维博客原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

    代码一

    1. SELECT t0.[comp_num] ,  
    2.        t0.[id] ,  
    3.        t0.[role_desc] ,  
    4.        t0.[role_issys] ,  
    5.        t0.[role_name] ,  
    6.        t0.[role_order] ,  
    7.        t0.[role_type]  
    8. FROM   ( SELECT    t1.[comp_num] ,  
    9.                    t1.[id] ,  
    10.                    t1.[role_desc] ,  
    11.                    t1.[role_issys] ,  
    12.                    t1.[role_name] ,  
    13.                    t1.[role_order] ,  
    14.                    t1.[role_type] ,  
    15.                    ROW_NUMBER() OVER ( ORDER BY t1.[role_desc] DESC ) AS [ROWNUMBER]  
    16.          FROM      [T_sys_role] AS t1  
    17.          WHERE     ( t1.[id] >= 0 )  
    18.        ) AS t0  
    19. WHERE  t0.[ROWNUMBER] BETWEEN ( 2 + 1 ) AND ( 2 + 2 )  
    20. ORDER BY t0.[role_desc] DESC   

    代码二

    1. SELECT TOP 16  
    2.         *  
    3. FROM    ( SELECT    a.id ,  
    4.                     a.cus_no ,  
    5.                     a.cus_name ,  
    6.                     a.cus_sname ,  
    7.                     a.cus_lastid AS cus_lastname ,  
    8.                     a.cus_tel ,  
    9.                     a.cus_city ,  
    10.                     a.cus_address ,  
    11.                     a.cus_note ,  
    12.                     ( SELECT    cc.con_name  
    13.                       FROM      T_cus_con cc  
    14.                       WHERE     id = a.con_id  
    15.                     ) AS con_name ,  
    16.                     ( SELECT    u.user_tname  
    17.                       FROM      t_sys_user AS u  
    18.                       WHERE     u.id = a.user_id  
    19.                     ) AS user_name ,  
    20.                     ( SELECT    STUFF(( SELECT  \',\' + u2.user_tname  \r\n;
    21.                                         FROM    t_sys_user AS u2  
    22.                                         WHERE   CHARINDEX(CAST(u2.id AS VARCHAR),  
    23.                                                           a.con_team) > 0  
    24.                                       FOR 
    25.                                         XML PATH(\'\')  
    26.                                       ), 1, 1, \'\')  
    27.                     ) AS con_team ,  
    28.                     a.con_is_pub ,  
    29.                     a.con_back ,  
    30.                     a.cus_createTime ,  
    31.                     b.*  
    32.           FROM      T_cus_base AS a  
    33.                     INNER JOIN T_cus_expvalue_10000 AS b ON a.id = b.cus_id  
    34.           WHERE     con_back = 0  
    35.                     AND ( user_id = 3  
    36.                           OR con_is_pub = 1  
    37.                         )  
    38.         ) AS T  
    39. ORDER BY id  
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5444, 'linq%e6%9f%a5%e8%af%a2%e5%88%86%e9%a1%b5', 'LINQ查询分页', '2014-09-12 12:33:10', '2019-03-25 21:29:22', '

    //查询分页
            public IPagination<TSysRole> GetListByPage(int pageIndex, int pageSize, int rowCount,
                Expression<Func<TSysRole, bool>> predicate)
            {
                string ordering;
                string orderType;


              IDictionary<string,teaCRM.Entity.teaCRMEnums.OrderEmum> orders=new Dictionary<string, teaCRMEnums.OrderEmum>();

                orders.Add(new KeyValuePair<string, teaCRMEnums.OrderEmum>("Id",teaCRMEnums.OrderEmum.Asc));
                orders.Add(new KeyValuePair<string, teaCRMEnums.OrderEmum>("RoleName", teaCRMEnums.OrderEmum.Desc));

                using (teaCRMDBContext db = new teaCRMDBContext())
                {
                    var roles = db.TSysRoles;
                    rowCount = roles.Count();
                    var prevCount = (pageIndex - 1) * pageSize;
                    var models = roles
                        .Skip(prevCount)
                        .Take(pageSize)
                        .Where(predicate);
                    foreach (var order in orders)
                    {
                      models=  models.OrderBy(String.Format("{0} {1}", order.Key, order.Value));
                    }
                    var sqlText = models.GetProperty("SqlText");
                    LogHelper.Debug("ELINQ Paging:<br/>" + sqlText.ToString());

                    return models.ToPagination(pageSize, pageSize, rowCount); ;
                }
            }

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5448, '20140913184002', '20140913184002', '2014-09-13 10:40:03', '2019-03-25 21:29:22', 'centos和windows在接受json数据时,头部不一样,windows多几个字节。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5449, '20140914123434', '20140914123434', '2014-09-14 04:34:37', '2019-03-25 21:29:22', '以前我不信 现在我相信 上帝为你关闭一扇门时,也会为你打开另一扇门', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5450, 'jquery-sends-sync-requests', 'jquery发送同步请求', '2014-09-17 09:26:38', '2019-03-25 21:29:22', '

     

    【版权声明:本文为特维博客原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

    1. var res = $.ajax({ url: "/api/settings/appMaker/isInstalled", data: { id: id, compNum: compNum, appType: appType }, async: false }).responseText;  
    2. var json_data = eval("(" + res+")");  
    3. var is_installed = json_data.Status;  
    4.  
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5452, 'json2js-reference', 'json2.js使用参考', '2014-09-17 09:48:35', '2019-03-25 21:29:22', '

    【版权声明:本文为特维博客原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

    json2.js的源码地址:

    https://github.com/douglascrockford/JSON-js

    Visual Studio用户可以直接通过Nuget来获得。

    json2.js提供了json的序列化和反序列化方法,可以将一个json对象转换成json字符串,也可以将一个json字符串转换成一个json对象。

    在页面中添加json2.js的引用。
    <script type="text/javascript" src="/CoreResource/JS/json2.min.js"></script>
    \r\n\r\n
    序列化方法
    \r\n\r\n
    var jsonObj = { id: \'01\', name: \'Tom\' };\r\nJSON.stringify(jsonObj);
    \r\n\r\n
    反序列化方法
    \r\n\r\n
    var jsonString = "{ id: \'01\', name: \'Tom\' }";\r\nJSON.parse(jsonString);
    \r\n\r\n

    如果认为此文对您有帮助,别忘了支持一下

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5454, 'artdialog-number-of-popup-box', 'artDialog弹出多个框', '2014-09-17 11:31:23', '2019-03-25 21:29:22', '

    【版权声明:本文为特维博客原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

    代码:

    1.  
    2. //通过id可以弹出多个框 14-09-17 By 唐有炜  
    3. function showMoreDialog(id,msg, okCallback,cancelCallback) {  
    4.     var d = dialog({  
    5.         id: id,  
    6.         title: \'温馨提示\',  
    7.         content: msg,  
    8.         okValue: \'确 定\',  
    9.         ok: okCallback,  
    10.         cancelValue: \'取消\',  
    11.         cancel: cancelCallback  
    12.     });  
    13.     d.showModal();  
    14. }  

    使用:

    1.  
    2. function del(ids) {  
    3.     console.log(ids);  
    4.     var compNum = $("#CompNum").val();  
    5.     var del_tips = "确认卸载该应用吗?";  
    6.     if (del_tips.indexOf(\',\') > 0) {  
    7.         var del_tips = "确认卸载选中应用吗?";  
    8.     }  
    9.     showMoreDialog("uninstall_dialog", "确认卸载该应用吗?", function() {  
    10.         var is_clear = false;  
    11.         showMoreDialog("clear_data_dialog", "是否同时删除数据和配置", function() {  
    12.             is_clear = true;  
    13.             alert(is_clear);  
    14.             $.ajax({  
    15.                 type: "get",  
    16.                 cache: false,  
    17.                 url: "/api/settings/appMaker/unInstall",  
    18.                 data: { ids: ids, compNum: compNum, is_clear: is_clear },  
    19.                 dataType: "json",  
    20.                 beforeSend: function() {  
    21.                     //showMsg("添加中,请稍后...");  
    22.                 },  
    23.                 complete: function() {  
    24.                     //showMsg("完成...");  
    25.                 },  
    26.                 success: function(result) {  
    27.                     //toLowerCase报错  
    28.                     //var status = result.Status.toLowerCase();  
    29.                     var status = result.Status;  
    30.                     if (status == true || status == "true" || status == "True") {  
    31.                         //刷新我的应用  
    32.      &\r\n#160;                  grid.bootgrid("reload");  
    33.                         showMsg("应用卸载成功!", "Success");  
    34.                     } else {  
    35.                         showMsg("系统异常,应用卸载失败!");  
    36.                     }  
    37.  
    38.                 },  
    39.                 error: function() {  
    40.                     showMsg("网络连接错误");  
    41.                 }  
    42.             });  
    43.         }, function() {  
    44.             alert(is_clear);  
    45.             $.ajax({  
    46.                 type: "get",  
    47.                 cache: false,  
    48.                 url: "/api/settings/appMaker/unInstall",  
    49.                 data: { ids: ids, compNum: compNum, is_clear: is_clear },  
    50.                 dataType: "json",  
    51.                 beforeSend: function() {  
    52.                     //showMsg("添加中,请稍后...");  
    53.                 },  
    54.                 complete: function() {  
    55.                     //showMsg("完成...");  
    56.                 },  
    57.                 success: function(result) {  
    58.                     //toLowerCase报错  
    59.                     //var status = result.Status.toLowerCase();  
    60.                     var status = result.Status;  
    61.                     if (status == true || status == "true" || status == "True") {  
    62.                         //刷新我的应用  
    63.                         grid.bootgrid("reload");  
    64.                         showMsg("应用卸载成功!", "Success");  
    65.                     } else {  
    66.                         showMsg("系统异常,应用卸载失败!");  
    67.                     }  
    68.  
    69.                 },  
    70.                 error: function() {  
    71.                     showMsg("网络连接错误");  
    72.             \r\n0;   }  
    73.             });  
    74.         });  
    75.  
    76.     }, function() {  
    77.         showMsg("您取消了卸载!", "Error");  
    78.         dialog.list["uninstall_dialog"].close().remove();  
    79.     });  
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5459, 'elinq%e5%ae%9e%e7%8e%b0%e4%ba%8b%e5%8a%a1', 'ELinq实现事务', '2014-09-17 11:55:45', '2019-03-25 21:29:22', '
    1. using (teaCRMDBContext db = new teaCRMDBContext())  
    2.            {  
    3.                if (db.Connection.State != ConnectionState.Open)  
    4.                {  
    5.                    db.Connection.Open();  
    6.                }  
    7.                var tran = db.Connection.BeginTransaction();  
    8.                try 
    9.                {  
    10.                    //do insert or delete  
    11.                    tran.Commit();  
    12.                    return true;  
    13.                }  
    14.                catch (Exception ex)  
    15.                {  
    16.                    tran.Rollback();  
    17.                    return false;  
    18.                }  
    19.                finally 
    20.                {  
    21.                    if (db.Connection.State != ConnectionState.Closed)  
    22.                    {  
    23.                        db.Connection.Close();  
    24.                    }  
    25.                }  
    26.            } 
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5461, 'jquery%e5%8e%9f%e7%94%9f%e7%9a%84%e7%9a%84ajax%e4%bd%bf%e7%94%a8', 'jquery原生的的ajax使用', '2014-09-22 09:43:20', '2019-03-25 21:29:22', '
    1. //提交数据  
    2.             $.ajax({  
    3.               type: "post",  
    4.               cache: false,  
    5.               url: "/Apps/CRM/Index/Edit/" + row.id,  
    6.               data: data,  
    7.               dataType: "json",  
    8.               beforeSend: function () {  
    9.                   //showMsg("添加中,请稍后...");  
    10.               },  
    11.               complete: function () {  
    12.                   //d.close().remove();  
    13.               },  
    14.               success: function (result) {  
    15.                   //toLowerCase报错  
    16.                   //var status = result.Status.toLowerCase();  
    17.                   var status = result.Status;  
    18.                   if (status == true || status == "true" || status == "True") {  
    19.                       showMsg(result.Msg, "Success");  
    20.                       //刷新数据  
    21.                       customer_grid_reload();  
    22.                   } else {  
    23.                       showMsg("系统异常!", "Error");  
    24.                   }  
    25.               },  
    26.               error: function () {  
    27.                   showMsg("网络连接错误");  
    28.               }  
    29.           }); 
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5463, 'asp-net-web-automatically-generated-api-documentation', 'Asp .NET Web Api 自动生成帮助文档', '2014-09-24 07:05:28', '2019-03-25 21:29:22', '

    【版权声明:本文为特维博客原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

    Install-Package Microsoft.AspNet.WebApi.HelpPage -Version 4.0.0

     

    \"2014-09-24_150451\"

     

     

    \"20140924150553\"

     

    http://www.cnblogs.com/JreeyQi/p/3976724.html

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5468, 'linq-sqlcommandbuilder', 'LINQ实现批量更新', '2014-09-24 11:59:13', '2019-03-25 21:29:22', '

    【版权声明:本文为特维博客原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

    代码一

    1. #region 使用LINQ批量更改TCusCon状态 2014-09-05 14:58:50 By 唐有炜  
    2.  
    3.        /// <summary>  
    4.        /// 使用LINQ批量更改TCusCon字段 2014-09-05 14:58:50 By 唐有炜:注意,字段与条件要一一对应(要更新的字段名不能重复)  
    5.        /// </summary>  
    6.        /// <param name="fields">要更新的字段(支持批量更新)</param>  
    7.        /// <param name="predicates">条件集合</param>  
    8.        /// <returns><c>true</c>更新状态</returns>  
    9.        public bool UpdateTCusConFieldsByLINQ(List<KeyValuePair<string,object>> fields,  
    10.            List<Expression<Func<TCusCon, bool>>> predicates)  
    11.        {  
    12.            using (teaCRMDBContext db = new teaCRMDBContext())  
    13.            {  
    14.                if (db.Connection.State != ConnectionState.Open)  
    15.                {  
    16.                    db.Connection.Open();  
    17.                }  
    18.                var tran = db.Connection.BeginTransaction();  
    19.                try 
    20.                {  
    21.     
    22.                    for (int i = 0; i < fields.Count; i++)  
    23.                    {  
    24.                        //当前字段  
    25.                        var key = fields[i].Key;  
    26.                        //当前字段要设置的值  
    27.                        var value = fields[i].Value;  
    28.                        //当前字段更新时的条件  
    29.                        var predicate = predicates[i];  
    30.  
    31.                        var entity = db.TCusCons.SingleOrDefault(predicate);  
    32.                        var propertyInfos = entity.GetType().GetProperties();  
    33.                        foreach (var p in propertyInfos)  
    34.                        {  
    35.                            if (p.Name == key)  
    36.                            {  
    37.                                p.SetValue(entity, value, null); //给对应属性赋值  
    38.                            }  
    39.                        }  
    40.          \r\n0;             db.TCusCons.Update(entity);  
    41.                    }  
    42.  
    43.                    tran.Commit();  
    44.                    LogHelper.Debug("TCusCon字段批量更新成功。");  
    45.                    return true;  
    46.                }  
    47.                catch (Exception ex)  
    48.                {  
    49.                    tran.Rollback();  
    50.                    LogHelper.Error("TCusCon字段批量更新异常:", ex);  
    51.                    return false;  
    52.                }  
    53.                finally 
    54.                {  
    55.                    if (db.Connection.State != ConnectionState.Closed)  
    56.                    {  
    57.                        db.Connection.Close();  
    58.                    }  
    59.                }  
    60.            }  
    61.        }  
    62.  
    63.        #endregion 

     

    代码二

    1. #region 更改联系人状态 2014-09-24 14:58:50 By 唐有炜  
    2.  
    3.        /// <summary>  
    4.        /// 更改联系人状态 2014-09-24 14:58:50 By 唐有炜  
    5.        /// </summary>  
    6.        /// <param name="ids">id集合(1,2,3)</param>  
    7.        /// <param name="status">状态(0)或者(1)</param>  
    8.        /// <param name="field">要更新的字段(ConTrash)</param>  
    9.        /// <returns>更新状态</returns>  
    10.        public bool UpdateContactStatus(string ids, int status, string field)  
    11.  
    12.        {  
    13.            var fields = new List<KeyValuePair<string, object>>();  
    14.            var predicates = new List<Expression<Func<TCusCon, bool>>>();  
    15.  
    16.            var idValues = Utils.StringToIntArray(ids, \',\');  
    17.            foreach (var idValue in idValues)  
    18.            {  
    19.                fields.Add(new KeyValuePair<string, object>(field, status));  
    20.                Expression<Func<TCusCon, bool>> predicate = c => c.Id == idValue;  
    21.                predicates.Add(predicate);  
    22.            }  
    23.            var uodataStatus = CusConDao.UpdateTCusConFieldsByLINQ(fields, predicates);  
    24.          \r\n60; return uodataStatus;  
    25.        }  
    26.  
    27.        #endregion 
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5471, 'iframe%e8%8e%b7%e5%8f%96%e7%88%b6%e3%80%81%e5%ad%90%e7%aa%97%e5%8f%a3%e7%9a%84%e6%96%b9%e6%b3%95', 'iframe获取父、子窗口的方法', '2014-09-25 02:15:18', '2019-03-25 21:29:22', '

    jquery、js调用iframe父窗口与子窗口元素的方法

    1. jquery在iframe子页面获取父页面元素代码如下:

    $("#objid",parent.document)

    2. jquery在父页面获取iframe子页面的元素
    代码如下:
    $("#objid",document.frames(\'iframename\').document)

    3.js在iframe子页面获取父页面元素代码如下:

    indow.parent.document.getElementByIdx_x("元素id");

    4.js在父页面获取iframe子页面元素代码如下:

    window.frames["iframe_ID"].document.getElementByIdx_x("元素id");

    5.子类iframe内调用父类函数:

    window.parent.func();

     

     

     

     

    1.  
    2. /**  
    3. *添加联系人  
    4. *如果客户id为空直接添加联系人,不为空,则添加当前客户对应的联系人  
    5. *@author terwer  
    6. *@version 1.0 2014/09/24   
    7. *@param customer_id 客户id(可为空)   
    8. *@return 无返回值  
    9. */ 
    10. function add(customer_id) {  
    11.     //parent.dialog.list["show_view"].close();  
    12.     var win_id = "show_add_contact";  
    13.     showTopWindow(win_id, "/Apps/CRM/Contact/Add/", "添加联系人", 800, 360, function() {  
    14.         var form_contact = $(window.top.frames["frm_"+win_id].document).find("#form_contact");  
    15.         var flag = window.top.document.getElementById("frm_" + win_id).contentWindow.form_valid();  
    16.         if (!flag) {  
    17.             return false;  
    18.         }  
    19.         var data = $(form_contact).serialize();  
    20.         var url = "/Apps/CRM/Index/Add/";  
    21.         if (customer_id != undefined) {  
    22.             url += customer_id;  
    23.         }  
    24.         console.log(data);  
    25.         console.log(url);  
    26.         return false;  
    27.  
    28.         $.ajax({  
    29.             type: "post",  
    30.             cache: false,  
    31.             url: url,  
    32.             data: data,  
    33.             dataType: "json",  
    34.             beforeSend: function() {  
    35.                 //showMsg("添加中,请稍后...");  
    36.             },  
    37.             complete: function() {  
    38.                 //d.close().remove();  
    39.             },  
    40.             success: function(result) {  
    41.                 //toLowerCase报错  
    42.                 //var status = result.Status.toLowerCase();  
    43.                 var status = result.Status;  
    44.                 if (status == true || status == "true" || status == "True") {  
    45.                     //在iframe里面打开弹出框并自动关闭  
    46.    \r\n                 showMsg(result.Msg, "Success");  
    47.                     //刷新数据  
    48.                     customer_grid_reload();  
    49.                 } else {  
    50.                     showMsg("系统异常!", "Error");  
    51.                 }  
    52.             },  
    53.             error: function() {  
    54.                 showMsg("网络连接错误");  
    55.             }  
    56.         });  
    57.  
    58.     });  
    59. }  

     

     

     

     

     

    1.  
    2.  
    3. //iframe里面弹出对话框并自动关闭  
    4. function showTopWindow(id, url, title, w, h, okCallback) {  
    5.     //在iframe里面打开弹出框并自动关闭  
    6.     var d=top.dialog({  
    7.         id: id,  
    8.         title: title,  
    9.         //url: url,//此方式不支持滚动条  
    10.         content: \'<iframe src="\' + url + \'" id="frm_\' + id + \'" name="frm_\' + id + \'" style="border-bottom: 1px solid #E5E5E5;" width="100%" height="100%" width="100%" frameborder="0" scrolling="auto"></iframe>\',  
    11.         width: w,  
    12.         height: h,  
    13.         left: 0,  
    14.         top: 0,  
    15.         fixed: true,  
    16.         resize: false,  
    17.         drag: false,  
    18.         lock: true,  
    19.         okValue: \'确 定\',  
    20.         ok: okCallback,  
    21.         cancelValue: \'取消\',  
    22.         cancel: function () {  
    23.             d.close().remove();  
    24.         }  
    25.     }).showModal();  
    26. }  
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5474, 'newtonsoft-json-jsonconvert-date-processing', 'Newtonsoft.Json JsonConvert日期处理', '2014-09-25 06:19:21', '2019-03-25 21:29:22', '

    \r\n 问题重现
    \r\n

    \r\n

    \r\n 在使用.NET MVC原生的JsonResult输出json数据时,如果使用\r\n

    \r\n
    \r\n

    \r\n [HttpPost]\r\n

    \r\n

    \r\n public JsonResult GetPagerData(int rows, int page, string sort, string order, string filterRules){
    \r\n
    \r\n

    \r\n

    \r\n //下面的日期格式有问题\r\n

    \r\n

    \r\n  return Json(gridData,JsonRequestBehavior.AllowGet);\r\n

    \r\n

    \r\n }\r\n

    \r\n
    \r\n

    \r\n 默认的时间格式是这样的\r\n

    \r\n

    \r\n \"\"\r\n

    \r\n

    \r\n 解决方案
    \r\n

    \r\n

    \r\n 不用Json()方法,将json输出改为使用下面的代码即可:\r\n

    \r\n
    \r\n

    \r\n //自定义日期格式\r\n

    \r\n

    \r\n var timeConverter =new Newtonsoft.Json.Converters.IsoDateTimeConverter {DateTimeFormat = \"yyyy-MM-dd HH:mm\"};\r\n

    \r\n

    \r\n return JsonConvert.SerializeObject(gridData, timeConverter); \r\n

    \r\n
    \r\n

    \r\n  \r\n

    \r\n

    \r\n \"\"\r\n

    \r\n

    \r\n  \r\n

    \r\n

    \r\n
    \r\n

    \r\n

    \r\n
    \r\n

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5476, 'js-date', 'js日期处理', '2014-09-27 06:11:40', '2019-03-25 21:29:22', '// 增加天\r\nfunction AddDays(date,value)\r\n{\r\ndate.setDate(date.getDate()+value);\r\n}\r\n// 增加月\r\nfunction AddMonths(date,value)\r\n{\r\ndate.setMonth(date.getMonth()+value);\r\n}\r\n// 增加年\r\nfunction AddYears(date,value)\r\n{\r\ndate.setFullYear(date.getFullYear()+value);\r\n}\r\n// 是否为今天\r\nfunction IsToday(date)\r\n{\r\nreturn IsDateEquals(date,new Date());\r\n}\r\n// 是否为当月\r\nfunction IsThisMonth(date)\r\n{\r\nreturn IsMonthEquals(date,new Date());\r\n}\r\n// 两个日期的年是否相等\r\nfunction IsMonthEquals(date1,date2)\r\n{\r\nreturn date1.getMonth()==date2.getMonth()&&date1.getFullYear()==date2.getFullYear();\r\n}\r\n// 判断日期是否相等\r\nfunction IsDateEquals(date1,date2)\r\n{\r\nreturn date1.getDate()==date2.getDate()&&IsMonthEquals(date1,date2);\r\n}\r\n// 返回某个日期对应的月份的天数\r\nfunction GetMonthDayCount(date)\r\n{\r\nswitch(date.getMonth()+1)\r\n{\r\ncase 1:case 3:case 5:case 7:case 8:case 10:case 12:\r\nreturn 31;\r\ncase 4:case 6:case 9:case 11:\r\nreturn 30;\r\n}\r\n//feb:\r\ndate=new Date(date);\r\nvar lastd=28;\r\ndate.setDate(29);\r\nwhile(date.getMonth()==1)\r\n{\r\nlastd++;\r\nAddDays(date,1);\r\n}\r\nreturn lastd;\r\n}\r\n// 返回两位数的年份\r\nfunction GetHarfYear(date)\r\n{\r\nvar v=date.getYear();\r\nif(v>9)return v.toString();\r\nreturn \"0\"+v;\r\n}\r\n// 返回月份(修正为两位数)\r\nfunction GetFullMonth(date)\r\n{\r\nvar v=date.getMonth()+1;\r\nif(v>9)return v.toString();\r\nreturn \"0\"+v;\r\n}\r\n// 返回日 (修正为两位数)\r\nfunction GetFullDate(date)\r\n{\r\nvar v=date.getDate();\r\nif(v>9)return v.toString();\r\nreturn \"0\"+v;\r\n}\r\n// 替换字符串\r\nfunction Replace(str,from,to)\r\n{\r\nreturn str.split(from).join(to);\r\n}\r\n// 格式化日期的表示\r\nfunction FormatDate(date,str)\r\n{\r\nstr=Replace(str,\"yyyy\",date.getFullYear());\r\nstr=Replace(str,\"MM\",GetFullMonth(date));\r\nstr=Replace(str,\"dd\",GetFullDate(date));\r\nstr=Replace(str,\"yy\",GetHarfYear(date));\r\nstr=Replace(str,\"M\",date.getMonth()+1);\r\nstr=Replace(str,\"d\",date.getDate());\r\nreturn str;\r\n}\r\n// 统一日期格式\r\nfunction ConvertDate(str)\r\n{\r\nstr=(str+\"\").replace(/^s*/g,\"\").replace(/s*$/g,\"\"); // 去除前后的空白\r\nvar d;\r\nif(/^[0-9]{8}$/.test(str)) // 20040226 -> 2004-02-26\r\n{\r\nd=new Date(new Number(str.substr(0,4)),new Number(str.substr(4,2))-1,new Number(str.substr(6,2)));\r\nif(d.getTime())return d;\r\n}\r\nd=new Date(str);\r\nif(d.getTime())return d;\r\nd=new Date(Replace(str,\"-\",\"/\"));\r\nif(d.getTime())return d;\r\nreturn null;\r\n}\r\n
      \r\n
    1. js时间差函数\r\n< LANGUAGE=javascript>\r\nalert(addDay(-30,1));\r\nalert(addDay(-30,2));\r\nalert(addDay(-30,3));\r\nalert(addDay(-30,0));\r\nfunction addDay(days,n)\r\n{\r\n//函数说明:days日期差,n代表如下含义。\r\nvar my_date_ago=new Date(new Date() - days * 24 * 60 * 60 * 1000 * -1);//days天的日期\r\nswitch (n)\r\n{\r\ncase 1:\r\n//返回年\r\nreturn(my_date_ago.getFullYear());\r\nbreak;\r\ncase 2:\r\n//返回月\r\nreturn(my_date_ago.getMonth()+1);\r\nbreak;\r\ncase 3:\r\n//返回日\r\nreturn(my_date_ago.getDate());\r\nbreak;\r\ndefault :\r\n//返回全部\r\nreturn(my_date_ago.getFullYear() + \"-\" + (my_date_ago.getMonth()+1) + \"-\" + my_date_ago.getDate());\r\nbreak;\r\n}\r\n}
    2. \r\n
    \r\n \r\n\r\n \r\n\r\n \r\n\r\n \r\n\r\n \r\n\r\n \r\n\r\n \r\n\r\n \r\n\r\n \r\n\r\n \r\n\r\n//日期格式化开始======================================================================\r\nDate.prototype.format = function(format) {\r\nvar o = {\r\n\"M+\": this.getMonth() + 1, //month\r\n\"d+\": this.getDate(), //day\r\n\"h+\": this.getHours(), //hour\r\n\"m+\": this.getMinutes(), //minute\r\n\"s+\": this.getSeconds(), //second\r\n\"q+\": Math.floor((this.getMonth() + 3) / 3), //quarter\r\n\"S\": this.getMilliseconds() //millisecond\r\n};\r\nif (/(y+)/.test(format))\r\nformat = format.replace(RegExp.$1,\r\n(this.getFullYear() + \"\").substr(4 - RegExp.$1.length));\r\nfor (var k in o)\r\nif (new RegExp(\"(\" + k + \")\").test(format))\r\nformat = format.replace(RegExp.$1,\r\nRegExp.$1.length == 1 ? o[k] :\r\n(\"00\" + o[k]).substr((\"\" + o[k]).length));\r\nreturn format;\r\n};\r\n\r\n//字符串转日期格式,strDate要转为日期格式的字符串\r\nfunction strToDate(strDate) {\r\nvar date = eval(\'new Date(\' + strDate.replace(/d+(?=-[^-]+$)/,\r\nfunction (a) { return parseInt(a, 10) - 1; }).match(/d+/g) + \')\');\r\nreturn date;\r\n}\r\n\r\n \r\n\r\n \r\n\r\n \r\n\r\nJS 月份相减\r\n\r\n 
    1. function test(){  
    2.     var mon=    getMonthNumber(\"2013-10-20\",\"2014-11-03\");  
    3.     alert(mon);  
    4. }  
    5.   
    6. //默认格式为\"2014-11-03\",根据自己需要改格式和方法 141103 By 唐有炜  
    7. //date1 起始日期  
    8. //date2 终止日期  
    9. function getMonthNumber(date1, date2) {  
    10.             var year1 = date1.substr(0, 4);  
    11.             var year2 = date2.substr(0, 4);  
    12.             var month1 = date1.substr(5, 2);  
    13.             var month2 = date2.substr(5, 2);  
    14.             var len = (year2 - year1) * 12 + (month2 - month1);  
    15.             //alert(len);  
    16.       
    17.             var day = date2.substr(8, 2) - date1.substr(8, 2);  
    18.               //alert(day);  
    19.       
    20.             if (day > 0) {  
    21.                 len += 1;  
    22.             }   
    23.             else if (day < 0)   
    24.             {  
    25.                 len -= 1;  
    26.             }  
    27.             return len;  
    28. }  
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5479, '%e5%90%84%e7%a7%8d%e7%bb%93%e6%9e%84%e4%bd%bf%e7%94%a8%e5%bf%83%e5%be%97', '各种结构使用心得', '2014-09-28 02:12:47', '2019-03-25 21:29:22', '

    一个字段用 KeyValuePair<string, object>

    一条记录用IDictionary<string,object>

    列表用IEnumerable<IDictionary<string,object>>

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5481, 'linq%e5%b9%b6%e8%a1%8c%e5%8c%96', 'LINQ并行化', '2014-09-28 06:25:23', '2019-03-25 21:29:22', '

    http://msdn.microsoft.com/zh-cn/magazine/cc163329.aspx

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5483, '20141003182840', '20141003182840', '2014-10-03 10:28:41', '2019-03-25 21:29:22', '在深圳,很纠结。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5485, '20141005182610', '20141005182610', '2014-10-05 10:26:10', '2019-03-25 21:29:22', '.net保底,向安卓进发。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5486, '20141005182638', '20141005182638', '2014-10-05 10:26:38', '2019-03-25 21:29:22', '近期目标,,完成两个实际安卓项目。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5487, 'eclipse-boot-error-solution', 'eclipse启动报错解决', '2012-10-08 15:59:41', '2019-03-25 21:29:22', '
    错误重现\r\n========\r\n\r\n[![2014-10-09_235623](http://bcs.duapp.com/terwer//2014-10-09_235623_thumb.jpg \"2014-10-09_235623\")](http://bcs.duapp.com/terwer//2014-10-09_235623.jpg)\r\n\r\n解决方案\r\n========\r\n\r\n找到**eclipse安装目录**下的**eclipse.ini**,加上 -vm 后面是jdk的完整地址,解决。\r\n\r\n代码如下:\r\n\r\n```ini\r\n-vm\r\nC:/Program Files/Java/jdk1.7.0_55/bin/javaw.exe\r\n-startup\r\nplugins/org.eclipse.equinox.launcher_1.3.0.v20140415-2008.jar\r\n–launcher.library\r\nplugins/org.eclipse.equinox.launcher.win32.win32.x86_64_1.1.200.v20140603-1326\r\n-product\r\norg.eclipse.epp.package.jee.product\r\n–launcher.defaultAction\r\nopenFile\r\n–launcher.XXMaxPermSize\r\n256M\r\n-showsplash\r\norg.eclipse.platform\r\n–launcher.XXMaxPermSize\r\n256m\r\n–launcher.defaultAction\r\nopenFile\r\n–launcher.appendVmargs\r\n-vmargs\r\n-Dosgi.requiredJavaVersion=1.6\r\n-Xms40m\r\n-Xmx512m\r\n```
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5507, 'java-keywords-in-the-study-notes-001', '重拾Java学习笔记001:java中的关键字', '2012-10-10 14:26:04', '2019-03-25 21:29:22', '

    【版权声明:本文为特维博客原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

    简介

    Abstract 抽象的
    一个Java语言中的关键字,用在类的声明中来指明一个类是不能被实例化的,但是可以被其它类继承。一个抽象类可以使用抽象方法,抽象方法不需要实现,但是需要在子类中被实现。

    break
    一个Java的关键字,用来改变程序执行流程,立刻从当前语句的下一句开始执行从。如果后面跟有一个标签,则从标签对应的地方开始执行

    case
    Java语言的关键字,用来定义一组分支选择,如果某个值和switch中给出的值一样,就会从该分支开始执行。

    catch
    Java的一个关键字,用来声明当try语句块中发生运行时错误或非运行时异常时运行的一个块。

    char
    Java语言的一个关键字,用来定义一个字符类型
    continue
    一个Java的关键字,用来打断当前循环过程,从当前循环的最后重新开始执行,如果后面跟有一个标签,则从标签对应的地方开始执行。

    do
    一个Java语言的关键字,用来声明一个循环,这个循环的结束条件可以通过while关键字设置

    double
    一个Java语言的关键字,用来定义一个double类型的变量

    else
    一个Java语言的关键字,如果if语句的条件不满足就会执行该语句。

    final
    一个Java语言的关键字。你只能定义一个实体一次,以后不能改变它或继承它。更严格的讲:一个final修饰的类不能被子类化,一个final修饰的方法不能被重写,一个final修饰的变量不能改变其初始值。

    finally
    一个Java语言的关键字,用来执行一段代码不管在前面定义的try语句中是否有异常或运行时错误发生。

    float
    一个Java语言的关键字,用来定义一个浮点数变量

    for
    一个Java语言的关键字,用来声明一个循环。程序员可以指定要循环的语句,推出条件和初始化变量。

    if
    Java编程语言的一个关键字,用来生成一个条件测试,如果条件为真,就执行if下的语句。

    implements
    Java(TM)编程语言的一个关键字,在类的声明中是可选的,用来指明当前类实现的接口。

    import
    Java(TM)编程语言的一个关键字,在源文件的开始部分指明后面将要引用的一个类或整个包,这样就不必在使用的时候加上包的名字。

    instanceof
    一个二操作数的Java(TM)语言关键字,用来测试第一个参数的运行时类型是否和第二个参数兼容。

    详情参考:http://rodney.cnblogs.com/archive/2005/08/18/instanceof.html

    int
    Java(TM)的一个关键字,用来定义一个整形变量

    interface
    Java(TM)的一个关键字,用来定义一系列的方法和常量。它可以被类实现,通过implements关键字。

    long
    Java语言的一个关键字,用来定义一个long类型的变量。

    private
    Java语言的一个关键字,用在方法或变量的声中。它表示这个方法或变量只能被这个类的其它元素所访问。

    protected
    Java语言的一个关键字,在方法和变量的声明中使用,它表示这个方法或变量只能被同一个类中的,子类中的或者同一个包中的类中的元素所访问。
    public
    Java语言的一个关键字,在方法和变量的声明中使用,它表示这个方法或变量能够被其它类中的元素访问。

    return
    Java语言的一个关键字,用来结束一个方法的执行。它后面可以跟一个方法声明中要求的值。

    short
    Java语言的关键字,用来定义一个short类型的变量。

    static
    Java语言的关键字,用来定义一个变量为类变量。类只维护一个类变量的拷贝,不管该类当前有多少个实例。"static" 同样能够用来定义一个方法为类方法。类方法通过类名调用而不是特定的实例,并且只能操作类变量。
    this
    Java语言的关键字,用来代表它出现的类的一个实例。this可以用来访问类变量和类方法。

    throw
    Java语言的关键字,允许用户抛出一个exception对象或者任何实现throwable的对象

    throws
    Java语言的关键字,用在方法的声明中来说明哪些异常这个方法是不处理的,而是提交到程序的更高一层。
    transient
    Java语言的关键字,用来表示一个域不是该对象串行化的一部分。当一个对象被串行化的时候,transient型变量的值不包括在串行化的表示中,然而非transient型的变量是被包括进去的。

    详情:http://www.blogjava.net/fhtdy2004/archive/2009/06/20/286112.html

    http://www.ibm.com/developerworks/cn/java/j-jtp06197.html

    try
    Java语言的关键字,用来定义一个可能抛出异常语句块。如果一个异常被抛出,一个可选的catch语句块会处理try语句块中抛出的异常。同时,一个finally语句块会被执行,无论一个异常是否被抛出。
    void
    Java语言的关键字,用在Java语言的方法声明中说明这个方法没有任何返回值。"void"也可以用来表示一句没有任何功能的语句。

    volatile
    Java语言的关键字,用在变量的声明中表示这个变量是被同时运行的几个线程异步修改的。
    while
    Java语言的一个关键字,用来定义一段反复执行的循环语句。循环的退出条件是while语句的一部分。
    关于break和continue。
    continue 语句与break语句相关,但较少用到。continue语句用于使其所在的for、while或do-while语句开始下一次循环。在while与 do-while语句中,continue语句的执行意味着立即执行测试部分;在for循环语句中,continue语句的执行则意味着使控制传递到增量 部分。

    关键字列表

    以下是java 关键字分类列表:(共50个,供大家参考)

    访问控制

    private 私有的
    protected 受保护的
    public 公共的

    类、方法和变量修饰符

    abstract 声明抽象
    class 类
    extends 扩允,继承
    final 终极,不可改变的
    implements实现
    interface 接口
    native 本地
    new 新,创建
    static 静态
    strictfp 严格,精准
    synchronized 线程,同步
    transient 短暂
    volatile 易失

    程序控制语句

    break 跳出循环
    continue 继续
    return 返回
    do 运行
    whi\r\nle 循环
    if 如果
    else 反之
    for 循环
    instanceof 实例
    switch 开关
    case 返回开关里的结果
    default 默认

    错误处理

    catch 处理异常
    finally 有没有异常都执行
    throw 抛出一个异常对象
    throws 声明一个异常可能被抛出
    try 捕获异常

    包相关
    import 引入
    package 包

    基本类型

    boolean 布尔型
    byte 字节型
    char 字符型
    double 双精度,
    float 浮点
    int 整型
    long 长整型
    short 短整型

    变量引用

    super 父类,超类
    this 本类
    void 无返回值

    后记

    识别java语言的关键字,特别要注意不要和其他语言如c/c++的关键字混淆。 其中const和goto是java的保留字。所有的关键字都是小写的,还有要注意true,false,null, friendly,sizeof不是java的关键字,但 是你不能把它们作为java标识符用。这里可能有不少朋友都和我一样有误解,但是这是java的游戏规则,查了sun官方解释才敢相信。切记java中 true ,false , null在java中不是关键字,也不是保留字,它们只是显式常量值,但是你在程序中不能使用它们作为标识符。为什么?我也不知道,但这是sun公司的 java规定,你要玩它的游戏不想遵守它的规则都不行呀。

    可以参考网址

    http://docs.oracle.com/javase/tutorial/java/nutsandbolts/_keywords.html

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5516, 'wordpress-bulk-added-for-the-article-and-remove-the-prefix', 'Wordpress批量为文章添加和去除前缀', '2014-10-10 15:22:44', '2019-03-25 21:29:22', '

    【版权声明:本文为特维博客原创,未经准许谢绝转载。如需转载,请务必在转载时注明本博客地址。】

    SQL代码如下:

    1. SELECT COUNT(*) FROM wp_posts WHERE post_title LIKE \'【原】%\';  
    2. SELECT post_title FROM wp_posts WHERE post_title LIKE \'【原】%\' LIMIT 0,10;  
    3. --删除  
    4. UPDATE wp_posts SET post_title=REPLACE(post_title,\'【原】\',\'\') WHERE post_title LIKE \'【原】%\';  
    5.  
    6. SELECT post_title,CONCAT(\'【原】\',post_title,\'\') FROM wp_posts WHERE post_title <> \'\' LIMIT 0,10;  
    7. --添加  
    8. UPDATE wp_posts SET post_title=CONCAT(\'【原】\',post_title,\'\') WHERE post_title LIKE \'【原】%\';  

     

    \"2014-10-10_233154\"

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5527, 'c-file-operations-summary', 'C#文件操作总结', '2014-10-11 03:44:14', '2019-03-25 21:29:22', 'System.IO.Path.GetFileNam(filePath)   //返回带扩展名的文件名
    System.IO.Path.GetFileNameWithoutExtension(filePath)  //返回不带扩展名的文件名
    System.IO.Path.GetDirectoryName(filePath)  //返回文件所在目录', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5530, 'net-mvc4-will-be-home-to-the-region-area-and-set-the-default-way-area', '.NET MVC4将Home转移到区域(Area)并设置默认Area的办法', '2014-10-11 11:27:27', '2019-03-25 21:29:22', '1、创建一个Area,命名为Home\r\n\r\n修改HomeAreaRegistration.cs(非常重要)\r\nusing System.Web.Mvc;\r\n\r\nnamespace Ed.Web.Areas.Home\r\n{\r\npublic class HomeAreaRegistration : AreaRegistration\r\n{\r\npublic override string AreaName\r\n{\r\nget { return \"Home\"; }\r\n}\r\n\r\npublic override void RegisterArea(AreaRegistrationContext context)\r\n{\r\ncontext.MapRoute(\r\n\"Home_default\",\r\n\"{controller}/{action}/{id}\",\r\nnew[] {\"Ed.Web.Areas.Home\"}, //默认控制器的命名空间 (这里一定要加,非常重要)\r\nnew {controller = \"Home\", action = \"Index\", id = UrlParameter.Optional}\r\n);\r\n}\r\n}\r\n}\r\n2、修改RouteConfig.cs\r\n\r\nroutes.MapRoute(\r\n\"Default\", // 路由名称\r\n\"{controller}/{action}/{id}\", // 带有参数的 URL\r\nnew {controller = \"Home\", action = \"Index\", id = UrlParameter.Optional}, // 参数默认值\r\nnew[] {\"Ed.Web.Areas.Home\"} //默认控制器的命名空间\r\n).DataTokens.Add(\"area\", \"Home\"); //默认area 的控制器名称', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5535, 'sorting-out-common-knowledge-in-java', 'Java常见知识点整理', '2014-10-11 15:59:24', '2019-03-26 05:22:09', '5、String是最基本的数据类型吗?\r\n\r\n 基本数据类型包括byte、int、char、long、float、double、boolean和short。\r\n java.lang.String类是final类型的,因此不可以继承这个http://www.cnblogs.com/yhason/archive/2012/05/08/2489932.html类、不能修改这个类。为了提高效率节省空间,我们应该用StringBuffer类\r\n6、int 和 Integer 有什么区别\r\n\r\n Java 提供两种不同的类型:引用类型和原始类型(或内置类型)。Int是java的原始数据类型,Integer是java为int提供的封装类。Java为每个原始类型提供了封装类。\r\n 引用类型和原始类型的行为完全不同,并且它们具有不同的语义。引用类型和原始类型具有不同的特征和用法,它们包括:大小和速度问题,这种类型以哪种类型的数据结构存储,当引用类型和原始类型用作某个类的实例数据时所指定的缺省值。对象引用实例变量的缺省值为 null,而原始类型实例变量的缺省值与它们的类型有关。\r\n7、String 和StringBuffer的区别\r\n\r\n JAVA平台提供了两个类:String和StringBuffer,它们可以储存和操作字符串,即包含多个字符的字符数据。这个String类提供了数值不可改变的字符串。而这个StringBuffer类提供的字符串进行修改。当你知道字符数据要改变的时候你就可以使用StringBuffer。典型地,你可以使用 StringBuffers来动态构造字符数据。\r\n8、运行时异常与一般异常有何异同?\r\n\r\n 异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误。java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。\r\n9、说出Servlet的生命周期,并说出Servlet和CGI的区别。\r\n\r\n Servlet被服务器实例化后,容器运行其init方法,请求到达时运行其service方法,service方法自动派遣运行与请求对应的doXXX方法(doGet,doPost)等,当服务器决定将实例销毁的时候调用其destroy方法。\r\n与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。\r\n10、说出ArrayList,Vector, LinkedList的存储性能和特性\r\n\r\n ArrayList 和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector由于使用了synchronized方法(线程安全),通常性能上较ArrayList差,而LinkedList使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。\r\n12、Collection 和 Collections的区别。\r\n\r\n  Collection是集合类的上级接口,继承与他的接口主要有Set 和List.\r\n Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。\r\n13、&和&&的区别。\r\n\r\n&是位运算符,表示按位与运算,&&是逻辑运算符,表示逻辑与(and)。\r\n15,HashMap和Hashtable的区别。\r\n\r\n  都属于Map接口的类,实现了将惟一键映射到特定的值上。\r\n  HashMap 类没有分类或者排序。它允许一个 null 键和多个 null 值。\r\n  Hashtable 类似于 HashMap,但是不允许 null 键和 null 值。它也比 HashMap 慢,因为它是同步的。\r\n15、final, finally, finalize的区别。\r\n\r\nfinal 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。\r\nfinally是异常处理语句结构的一部分,表示总是执行。\r\nfinalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。\r\n16、sleep() 和 wait() 有什么区别?\r\n\r\n sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,把执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。\r\nwait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。\r\n17、Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型?\r\n\r\n 方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被\"屏蔽\"了。如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。\r\n19、同步和异步有何异同,在什么情况下分别使用他们?举例说明。\r\n\r\n 如果数据将在线程间共享。例如正在写的数据以后可能被另一个线程读到,或者正在读的数据可能已经被另一个线程写过了,那么这些数据就是共享数据,必须进行同步存取。\r\n当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步编程,在很多情况下采用异步途径往往更有效率。\r\n20、abstract class和interface有什么区别?\r\n\r\n 声明方法的存在而不去实现它的类被叫做抽象类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。不能创建abstract 类的实例。然而可以创建一个变量,其类型是一个抽象类,并让它指向具体子类的一个实例。不能有抽象构造函数或抽象静态方法。Abstract 类的子类为它们父类中的所有抽象方法提供实现,否则它们也是抽象类为。取而代之,在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法。\r\n 接口(interface)是抽象类的变体。在接口中,所有方法都是抽象的。多继承性可通过实现这样的接口而获得。接口中的所有方法都是抽象的,没有一个有程序体。接口只可以定义static final成员变量。接口的实现与子类相似,除了该实现类不能从接口定义中继承行为。当类实现特殊接口时,它定义(即将程序体给予)所有这种接口的方法。然后,它可以在实现了该接口的类的任何对象上调用接口的方法。由于有抽象类,它允许使用接口名作为引用变量的类型。通常的动态联编将生效。引用可以转换到接口类型或从接口类型转换,instanceof 运算符可以用来决定某对象的类是否实现了接口。\r\n22、forward 和redirect的区别\r\n\r\n forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器,浏览器根本不知道服务器发送的内容是从哪儿来的,所以它的地址栏中还是原来的地址。\r\nredirect就是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址,一般来说浏览器会用刚才请求的所有参数重新请求,所以session,request参数都可以获取。\r\n24、Static Nested Class 和 Inner Class的不同。\r\n\r\n Static Nested Class是被声明为静态(static)的内部类,它可以不依赖于外部类实例被实例化。而通常的内部类需要在外部类实例化后才能实例化。\r\n25、JSP中动态INCLUDE与静态INCLUDE的区别?\r\n\r\n 动态INCLUDE用jsp:include动作实现它总是会检查所含文件中的变化,适合用于包含动态页面,并且可以带参数。\r\n静态INCLUDE用include伪码实现,定不会检查所含文件的变化,适用于包含静态页面< %@ include file=\"included.htm\" %>\r\n26、什么时候用assertion。\r\n\r\nassertion(断言)在软件开发中是一种常用的调试方式,很多开发语言中都支持这种机制。在实现中,assertion就是在程序中的一条语句,它对一个boolean表达式进行检查,一个正确程序必须保证这个boolean表达式的值为true;如果该值为false,说明程序已经处于不正确的状态下,系统将给出警告或退出。一般来说,assertion用于保证程序最基本、关键的正确性。assertion检查通常在开发和测试时开启。为了提高性能,在软件发布后,assertion检查通常是关闭的。\r\n36、说出数据连接池的工作机制是什么?\r\n\r\n连接客户端程序需要连接时,池驱动程序会返回一个未使用的池连接并', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5539, 'back-to-java-study-notes-002java-notes-in-depth-analysis', '重拾Java学习笔记002:java中的注解深度剖析', '2014-10-14 00:49:56', '2019-03-25 21:29:22', 'http://soundycui.iteye.com/blog/1012765', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5541, 'because-the-web-server-on-the-isapi-and-cgi-restrictions-list-settings-the-page-you-requested-cannot-be-provided-solutions', '由于 Web 服务器上的“ISAPI 和 CGI 限制”列表设置,无法提供您请求的页面解决方案', '2014-10-14 02:16:35', '2019-03-25 21:29:22', '
    \r\n

    处理【由于 Web 服务器上的“ISAPI 和 CGI 限制”列表设置,无法提供您请求的页面】 详细错误:HTTP 错误 404.2 - Not Found. 由于 Web 服务器上的“ISAPI 和 CGI 限制”列表设置,无法提供您请求的页面.

    \r\n

    出现环境:win7 + IIS7.0

    \r\n

    解决办法:IIS的根节点->右侧“ISAPI和CGI限制”->把禁止的DotNet版本项设置为允许,即可~

    \r\n

    \"\"

    \r\n\r\n
    \r\n
    \r\n\r\n
    \r\n\r\n启明星工作室提供企业网站相关建设,会议室预定等软件\r\n具体请访问官网 http://www.dotnetcms.org
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5543, 'js-iframe-parent-child-window-parent-element-to-invoke-the-methods-of-the-page-top-to-explain', 'JS iframe父子页面元素调用方法 window parent top 解释', '2014-10-14 02:26:08', '2019-03-25 21:29:22', '父窗口调用子窗口\r\nvar hasMore = parent.document.getElementByIdx_x_x_x(\"hasMore\").value;\r\n子窗口调用父窗口\r\ndocument.frames[\"ifrmBoxFrame\"].me.preLoadBoxGrid();\r\nwindow.frames[\"iframe_ID\"].document.getElementByIdx_x_x_x(\"iframe_document_object\"­).object_attribute = attribute_value\r\n\r\nwindow\r\n是对当前窗口自身的引用\r\n如:window.returnValue = ret;\r\nwindow.close();\r\ntop\r\n返回顶层窗口,即浏览器窗口。\r\n如:top.frames[tabID].location = url;\r\ntop.document.frames(\"ifrmBoxFrame\").me.executeQueryCond();\r\nparent\r\n返回父窗口\r\n如:parent.$(\"Insheet_FrameTable\").src = \"\";\r\nparent.frames[\"Insheet_FrameSheetList\"].initInsheetList(false);\r\n
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5545, 'restore-java-learning-notes-003-in-depth-analysis-of-anonymous-inner-classes-in-java', '重拾Java学习笔记003:深度剖析Java中的匿名内部类', '2012-10-17 10:04:08', '2019-03-25 21:29:22', '未完待续', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5547, '5547', '联合分隔符组成的字符串', '2014-10-18 11:08:54', '2019-03-25 21:29:22', '
    1. /// <summary>  
    2.        /// 联合分隔符组成的字符串 14-10-18 By 唐有炜  
    3.        /// </summary>  
    4.        /// <param name="str1">a|b|,a2|b2,a3|b3</param>  
    5.        /// <param name="str2">c,d,e</param>  
    6.        /// <param name="split">,</param>  
    7.        /// <returns>a|b|c,a2|b2|d,a3|b3|e</returns>  
    8.        public static string UnionStringsBySplit(string str1,string str2,char split)  
    9.        {  
    10.            string result="";  
    11.            var arr1 = str1.Split(split);  
    12.            for (int i = 0; i < arr1.Length; i++)  
    13.            {  
    14.                var tempArr1 = arr1[i];  
    15.                var arr2 = str2.Split(split);  
    16.                tempArr1 +="|"+ arr2[i];  
    17.                result += tempArr1;  
    18.            }  
    19.            result = result.TrimEnd(\'|\');  
    20.            return result;  
    21.        } 
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5552, 'question-about-win7-cant-connect-to-the-visual-studio-development-server', '关于win7无法连接到visual studio开发服务器的问题', '2014-10-21 01:18:26', '2019-03-25 21:29:22', '今天我的vs2010也出现了这个问题。网上搜索了一下,遇到同样问题的人还真不少,如下图所示:\r\n
    \r\n
    \"6597402918680952772\"
    \r\n
    \r\n
    可是网友给出的解决办法,实在不怎么样。有的建议更改端口,有的建议关闭防火墙。关闭防火墙倒是一个比较简单的办法。
    \r\n
    可是又想开着防火墙又想能够运行vs,于是我终于找到了一个两全其美的办法。
    \r\n
    \r\n
    \"6598194567051402279\"
    \r\n
    \r\n
    点击【允许运行另外一程序】,然后添加vs的运行文件就ok了。
    \r\n
    \r\n
    现在我的防火墙和vs并行了,good!
    \r\n
    \r\n
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5561, '20141021132130', '20141021132130', '2014-10-21 05:21:28', '2019-03-25 21:29:22', '圆方项目接近尾声。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5562, 'implements-a-custom-field-using-reflection-and-dynamic-keyword-queries', '利用反射和dynamic关键字实现自定义字段查询', '2014-10-21 10:10:31', '2019-03-25 21:29:22', 'IDao\r\n\r\n/// <summary>\r\n/// 根据条件查询某些字段(LINQ 动态查询)\r\n/// </summary>\r\n/// <param name=\"selector\">要查询的字段(格式:new(ID,Name))</param>\r\n/// <param name=\"predicate\">筛选条件(id==1)</param>\r\n/// <returns></returns>\r\nIQueryable<Object> GetFields(string selector, string predicate);\r\n\r\n \r\n\r\nDao\r\n\r\n/// <summary>\r\n/// 根据条件查询某些字段(LINQ 动态查询)\r\n/// </summary>\r\n/// <param name=\"selector\">要查询的字段(格式:new(ID,Name))</param>\r\n/// <param name=\"predicate\">筛选条件(id=0)</param>\r\n/// <returns></returns>\r\npublic IQueryable<Object> GetFields(string selector, string predicate)\r\n{\r\nusing (EdDBContext db=new EdDBContext())\r\n{\r\nvar model = db.TSysUsers.Where(predicate).Select(selector);\r\nvar sqlText = model.GetProperty(\"SqlText\");\r\nLogHelper.Debug(sqlText.ToString());\r\nreturn (IQueryable<object>) model;\r\n}\r\n}\r\n\r\nService层省略\r\n\r\n \r\n\r\nWeb层\r\n\r\n#region 依赖注入 2014-10-16 15:05:36 By 唐有炜\r\npublic ISysUserService SysUserService { set; get; }\r\npublic ISysDepartmentService SysDepartmentService { set; get; }\r\n#endregion\r\n\r\n使用\r\n\r\npublic void TestFunction(){\r\n\r\nvar userId = Session[EdKeys.SESSION_USER_ID].ToString();\r\ndynamic depObj = SysUserService.GetFields(\"NEW(DepId)\", String.Concat(new[] { \"Id=\", userId })).FirstOrDefault();\r\n\r\nvar depId = depObj.DepId.ToString();\r\ndynamic depObj2 = SysDepartmentService.GetFields(\"NEW(DepCode)\", String.Concat(new[] { \"Id=\", depId })).FirstOrDefault();\r\n\r\nvar depCode = depObj2.DepCode.ToString();\r\n\r\n}\r\n\r\n \r\n\r\n \r\n\r\n ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5567, 'linq-study-notes-004union-all-union-intersect-operation', 'LINQ学习笔记004:LINQ to Entities 查询中的表达式', '2014-10-23 09:54:41', '2019-03-25 21:29:22', '

    详情请参考:http://msdn.microsoft.com/zh-cn/library/bb399367(v=vs.100).aspx

    \r\n\r\n

    LINQ to Entities 中的表达式

    \r\n

    表达式是求值结果可以为单个值、对象、方法或命名空间的一段代码。 表达式可以包含文本值、方法调用、运算符及其操作数,或者简单名称。 简单名称可以是变量名、类型成员名、方法参数名、命名空间名或类型名。 表达式可以使用运算符(运算符又可使用其他表达式作为参数)或方法调用(方法调用的参数又可以是其他方法调用)。 因此,表达式可以非常简单,也可以极其复杂。

    \r\n

    在 LINQ to Entities 查询中,表达式可以包含 System.Linq.Expressions 命名空间中的类型所允许的任何内容,包括 lambda 表达式。 可在 LINQ to Entities 查询中使用的表达式是可用来查询 实体框架 的表达式的超集。 对 实体框架 的查询中使用的表达式仅限于 ObjectQuery<T> 和基础数据源所支持的运算。

    \r\n\r\n

    LINQ to Entities 中的查询

    \r\n

    查询是一种从数据源检索数据的表达式。 查询通常用专用查询语言表示,如用于关系数据库的 SQL 和用于 XML 的 XQuery。 因此,开发人员对于他们查询的每种类型的数据源或数据格式,都不得不学习一种新的查询语言。 语言集成查询 (LINQ) 为跨各种数据源和格式处理数据提供了一种更简单的、一致的模型。 在 LINQ 查询中,您始终可以使用编程对象。

    \r\n

    LINQ 查询操作包含三个操作:获得一个或多个数据源、创建查询并执行查询。

    \r\n

    可以通过 LINQ 查询实现 IEnumerable 泛型接口或 IQueryable 泛型接口的数据源。 ObjectQuery 泛型类(可实现 IQueryable 泛型接口)的实例可充当 LINQ to Entities 查询的数据源。 ObjectQuery 泛型类表示一个查询,该查询返回零个或多个类型化对象的集合。 您还可以通过使用 C# 关键字 var(在 Visual Basic 中为 Dim)让编译器推断实体的类型。

    \r\n

    在查询中,指定您要从数据源中检索的准确信息。 查询也可以指定返回信息之前信息的排序、分组和表现方式。 在 LINQ 中,查询存储在变量中。 如果查询返回一系列值,则查询变量本身必须为可查询的类型。 此查询变量不执行任何操作,也不返回任何数据;它只存储查询信息。 创建查询后必须执行该查询以检索任何数据。

    \r\n \r\n

    \r\n

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5571, '20141023225318', '20141023225318', '2014-10-23 14:53:14', '2019-03-25 21:29:22', '完成项目,有两种心态,一种是采用最快的但可能难于扩展的架构先做成能用的,一种是使用精心设计的架构用心完成,我始终追求第二种。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5573, 'architect-richter-substitution-principle-liskov-substitution-principle-lsp', '架构师必备之里氏替换原则(Liskov Substitution Principle, LSP)', '2014-10-24 14:18:46', '2019-03-25 21:29:22', '1 什么是里氏代换原则\r\n\r\n 里氏代换原则是由麻省理工学院(MIT)计算机科学实验室的Liskov女士,在1987年的OOPSLA大会上发表的一篇文章《Data Abstraction and Hierarchy》里面提出来的,主要阐述了有关继承的一些原则,也就是什么时候应该使用继承,什么时候不应该使用继承,以及其中的蕴涵的原理。2002年,我们前面单一职责原则中提到的软件工程大师Robert C. Martin,出版了一本《Agile Software Development Principles Patterns and Practices》,在文中他把里氏代换原则最终简化为一句话:“Subtypes must be substitutable for their base types”。也就是,子类必须能够替换成它们的基类。\r\n 我们把里氏代换原则解释得更完整一些:在一个软件系统中,子类应该可以替换任何基类能够出现的地方,并且经过替换以后,代码还能正常工作。\r\n\r\n2 第一个例子:正方形不是长方形\r\n “正方形不是长方形”是一个理解里氏代换原则的最经典的例子。在数学领域里,正方形毫无疑问是长方形,它是一个长宽相等的长方形。所以,我们开发的一个与几何图形相关的软件系统中,让正方形继承自长方形是顺利成章的事情。现在,我们截取该系统的一个代码片段进行分析:\r\n长方形类Rectangle:\r\nclass Rectangle {\r\n double length;\r\n double width;\r\n public double getLength() { return length; }\r\n public void setLength(double height) { this.length = length; }\r\n public double getWidth() { return width; }\r\n public void setWidth(double width) { this.width = width; }\r\n}\r\n正方形类Square:\r\nclass Square extends Rectangle {\r\n public void setWidth(double width) {\r\n super.setLength(width);\r\n super.setWidth(width);\r\n }\r\n public void setLength(double length) {\r\n super.setLength(length);\r\n super.setWidth(length);\r\n }\r\n}\r\n 由于正方形的度和宽度必须相等,所以在方法setLength和setWidth中,对长度和宽度赋值相同。类TestRectangle是我们的软件系统中的一个组件,它有一个resize方法要用到基类Rectangle,resize方法的功能是模拟长方形宽度逐步增长的效果:\r\n 测试类TestRectangle:\r\nclass TestRectangle {\r\n public void resize(Rectangle objRect) {\r\n while(objRect.getWidth() <= objRect.getLength() ) {\r\n objRect.setWidth( objRect.getWidth () + 1 );\r\n }\r\n }\r\n}\r\n 我们运行一下这段代码就会发现,假如我们把一个普通长方形作为参数传入resize方法,就会看到长方形宽度逐渐增长的效果,当宽度大于长度,代码就会停止,这种行为的结果符合我们的预期;假如我们再把一个正方形作为参数传入resize方法后,就会看到正方形的宽度和长度都在不断增长,代码会一直运行下去,直至系统产生溢出错误。所以,普通的长方形是适合这段代码的,正方形不适合。\r\n 我们得出结论:在resize方法中,Rectangle类型的参数是不能被Square类型的参数所代替,如果进行了替换就得不到预期结果。因此,Square类和Rectangle类之间的继承关系违反了里氏代换原则,它们之间的继承关系不成立,正方形不是长方形。\r\n\r\n3 第二个例子:鸵鸟不是鸟\r\n “鸵鸟非鸟”也是一个理解里氏代换原则的经典的例子。“鸵鸟非鸟”的另一个版本是“企鹅非鸟”,这两种说法本质上没有区别,前提条件都是这种鸟不会飞。生物学中对于鸟类的定义:“恒温动物,卵生,全身披有羽毛,身体呈流线形,有角质的喙,眼在头的两侧。前肢退化成翼,后肢有鳞状外皮,有四趾”。所以,从生物学角度来看,鸵鸟肯定是一种鸟。\r\n我们设计一个与鸟有关的系统,鸵鸟类顺理成章地由鸟类派生,鸟类所有的特性和行为都被鸵鸟类继承。大多数的鸟类在人们的印象中都是会飞的,所以,我们给鸟类设计了一个名字为fly的方法,还给出了与飞行相关的一些属性,比如飞行速度(velocity)。\r\n 鸟类Bird:\r\nclass Bird {\r\n double velocity;\r\n public fly() { //I am flying; };\r\n\r\n public setVelocity(double velocity) { this.velocity = velocity; };\r\n public getVelocity() { return this.velocity; };\r\n}\r\n 鸵鸟不会飞怎么办?我们就让它扇扇翅膀表示一下吧,在fly方法里什么都不做。至于它的飞行速度,不会飞就只能设定为0了,于是我们就有了鸵鸟类的设计。\r\n 鸵鸟类Ostrich:\r\nclass Ostrich extends Bird {\r\n public fly() { //I do nothing; };\r\n public setVelocity(double velocity) { this.velocity = 0; };\r\n public getVelocity() { return 0; };\r\n}\r\n 好了,所有的类都设计完成,我们把类Bird提供给了其它的代码(消费者)使用。现在,消费者使用Bird类完成这样一个需求:计算鸟飞越黄河所需的时间。\r\n 对于Bird类的消费者而言,它只看到了Bird类中有fly和getVelocity两个方法,至于里面的实现细节,它不关心,而且也无需关心,于是给出了实现代码:\r\n 测试类TestBird:\r\nclass TestBird {\r\n public calcFlyTime(Bird bird) {\r\n try{\r\n double riverWidth = 3000;\r\n System.out.println(riverWidth / bird.getVelocity());\r\n }catch(Exception err){\r\n System.out.println(\"An error occured!\");\r\n }\r\n };\r\n}\r\n 如果我们拿一种飞鸟来测试这段代码,没有问题,结果正确,符合我们的预期,系统输出了飞鸟飞越黄河的所需要的时间;如果我们再拿鸵鸟来测试这段代码,结果代码发生了系统除零的异常,明显不符合我们的预期。\r\n 对于TestBird类而言,它只是Bird类的一个消费者,它在使用Bird类的时候,只需要根据Bird类提供的方法进行相应的使用,根本不会关心鸵鸟会不会飞这样的问题,而且也无须知道。它就是要按照“所需时间 = 黄河的宽度 / 鸟的飞行速度”的规则来计算鸟飞越黄河所需要的时间。\r\n 我们得出结论:在calcFlyTime方法中,Bird类型的参数是不能被Ostrich类型的参数所代替,如果进行了替换就得不到预期结果。因此,Ostrich类和Bird类之间的继承关系违反了里氏代换原则,它们之间的继承关系不成立,鸵鸟不是鸟。\r\n\r\n\r\n4 鸵鸟到底是不是鸟?\r\n “鸵鸟到底是不是鸟”,鸵鸟是鸟也不是鸟,这个结论似乎就是个悖论。产生这种混乱有两方面的原因:\r\n原因一:对类的继承关系的定义没有搞清楚。\r\n 面向对象的设计关注的是对象的行为,它是使用“行为”来对对象进行分类的,只有行为一致的对象才能抽象出一个类来。我经常说类的继承关系就是一种“Is-A”关系,实际上指的是行为上的“Is-A”关系,可以把它描述为“Act-As”。关于类的继承的细节,我们可以单独再讲。\r\n 我们再来看“正方形不是长方形”这个例子,正方形在设置长度和宽度这两个行为上,与长方形显然是不同的。长方形的行为:设置长方形的长度的时候,它的宽度保持不变,设置宽度的时候,长度保持不变。正方形的行为:设置正方形的长度的时候,宽度随之改变;设置宽度的时候,长度随之改变。所以,如果我们把这种行为加到基类长方形的时候,就导致了正方形无法继承这种行为。我们“强行”把正方形从长方形继承过来,就造成无法达到预期的结果。\r\n “鸵鸟非鸟”基本上也是同样的道理。我们一讲到鸟,就认为它能飞,有的鸟确实能飞,但不是所有的鸟都能飞。问题就是出在这里。如果以“飞”的行为作为衡量“鸟”的标准的话,鸵鸟显然不是鸟;如果按照生物学的划分标准:有翅膀、有羽毛等特性作为衡量“鸟”的标准的话,鸵鸟理所当然就是鸟了。鸵鸟没有“飞”的行为,我们强行给它加上了这个行为,所以在面对“飞越黄河”的需求时,代码就会出现运行期故障。\r\n\r\n\r\n原因二:设计要依赖于用户要求和具体环境。\r\n\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5576, 'wpf-learning-note-001-centered-window', 'WPF学习笔记001:窗口居中', '2014-10-26 08:11:24', '2019-03-25 21:29:22', '<Window Title="Window1" Height="300" Width="300" WindowStartupLocation="CenterScreen"> \r\n

    \r\n
    \r\n

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5580, 'java-interview-summary', 'Java面试大全(一)', '2014-10-26 12:23:14', '2019-11-27 22:51:27', '**Q1:面向对象的特征有哪些方面?**\r\n\r\nA1:面向对象的特征主要有以下几个方面: \r\n\r\n- 抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面。抽象只关注对象有哪些属性和行为,并不关注这些行为的细节是什么。 \r\n\r\n- 继承:继承是从已有类得到继承信息创建新类的过程。提供继承信息的类被称为父类(超类、基类);得到继承信息的类被称为子类(派生类)。继承让变化中的软件系统有了一定的延续性,同时继承也是封装程序中可变因素的重要手段(如果不能理解请阅读阎宏博士的《Java与模式》或《设计模式精解》中关于桥梁模式的部分)。 \r\n\r\n- 封装:通常认为封装是把数据和操作数据的方法绑定起来,对数据的访问只能通过已定义的接口。面向对象的本质就是将现实世界描绘成一系列完全自治、封闭的对象。我们在类中编写的方法就是对实现细节的一种封装;我们编写一个类就是对数据和数据操作的封装。可以说,封装就是隐藏一切可隐藏的东西,只向外界提供最简单的编程接口(可以想想普通洗衣机和全自动洗衣机的差别,明显全自动洗衣机封装更好因此操作起来更简单;我们现在使用的智能手机也是封装得足够好的,因为几个按键就搞定了所有的事情)。 \r\n\r\n- 多态性:多态性是指允许不同子类型的对象对同一消息作出不同的响应。简单的说就是用同样的对象引用调用同样的方法但是做了不同的事情。多态性分为编译时的多态性和运行时的多态性。如果将对象的方法视为对象向外界提供的服务,那么运行时的多态性可以解释为:当A系统访问B系统提供的服务时,B系统有多种提供服务的方式,但一切对A系统来说都是透明的(就像电动剃须刀是A系统,它的供电系统是B系统,B系统可以使用电池供电或者用交流电,甚至还有可能是太阳能,A系统只会通过B类对象调用供电的方法,但并不知道供电系统的底层实现是什么,究竟通过何种方式获得了动力)。方法重载(overload)实现的是编译时的多态性(也称为前绑定),而方法重写(override)实现的是运行时的多态性(也称为后绑定)。 \r\n运行时的多态是面向对象最精髓的东西,要实现多态需要做两件事: \r\n1). 方法重写(子类继承父类并重写父类中已有的或抽象的方法); \r\n2). 对象造型(用父类型引用引用子类型对象,这样同样的引用调用同样的方法就会根据子类对象的不同而表现出不同的行为)。\r\n\r\n**Q2:访问修饰符public,private,protected,以及不写(默认)时的区别?**\r\n\r\n| 修饰符 | 当前类 | 同 包 | 子 类 | 其他包 |\r\n| ---- | ---- | ---- | ---- | ---- |\r\n| public | √ | √ | √ | √ |\r\n| protected | √ | √ | √ | × |\r\n| default | √ | √ | × | × |\r\n| private | √ | × | × | × |\r\n\r\n**Q3:String 是最基本的数据类型吗?**\r\n\r\nA3:不是。Java中的基本数据类型只有8个:byte、short、int、long、float、double、char、boolean;除了基本类型(primitive type),剩下的都是引用类型(reference type),Java 5以后引入的枚举类型也算是一种比较特殊的引用类型。 \r\n\r\n**Q4:float f=3.4;是否正确?**\r\n\r\nA4:不正确。3.4是双精度数,将双精度型(double)赋值给浮点型(float)属于下转型(down-casting,也称为窄化)会造成精度损失,因此需要强制类型转换 `float f =(float)3.4;` 或者写成 `float f =3.4f`。\r\n\r\n**Q5:short s1 = 1; s1 = s1 + 1;有错吗?short s1 = 1; s1 += 1;有错吗? **\r\n\r\nA5:对于 `short s1 = 1; s1 = s1 + 1;` 由于1是int类型,因此s1+1运算结果也是int 型,需要强制转换类型才能赋值给short型。而 `short s1 = 1; s1 += 1;` 可以正确编译,因为s1+= 1;相当于s1 = (short)(s1 + 1);其中有隐含的强制类型转换。\r\n# 参考\r\n1 http://www.cnblogs.com/xing901022/p/3975626.html#3038997\r\n\r\n2 http://www.cnblogs.com/michaellfx/p/3994885.html\r\n\r\n3 http://www.cnblogs.com/liuzhi/p/4036210.html\r\n\r\n4 http://www.cnblogs.com/ricky52529/p/4042643.html\r\n\r\n5 http://www.cnblogs.com/rookiebob/p/4036870.html\r\n\r\n6 http://www.cnblogs.com/liuzhi/p/4036211.html\r\n\r\n7 http://www.cnblogs.com/gune/articles/4042970.html\r\n\r\n8 http://www.cnblogs.com/chen1314/p/4050976.html\r\n\r\n9 http://www.cnblogs.com/yangsc/p/4038933.html\r\n\r\n10 http://www.cnblogs.com/ccsccs/articles/4039712.html\r\n\r\n11 http://www.cnblogs.com/mfrbuaa/p/4039655.html', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5588, 'c-interview-summary', 'C++面试汇总', '2014-10-26 12:31:48', '2019-03-25 21:29:22', '1 http://www.cnblogs.com/binxindoudou/articles/4049906.html', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5594, 'elinq-exceptions-thrown-by-sql-server-version-sysdatetime-can-not-recognize-the-built-in-function-name', 'Elinq SQL Server版本引发的异常:'SYSDATETIME' 不是可以识别的内置函数名称', '2014-10-26 13:08:51', '2019-03-25 21:29:22', '今天新项目上传到服务器数据一直不显示,看日志发现:\r\n\r\n异常时间:2014-10-26 21:01:24,401 [5]\r\n异常级别:ERROR\r\n日志标志:logerror\r\n异常信息:\r\n【附加信息】 : 获取PregnanterInfo分页列表失败。\r\n【异常类型】:QueryException\r\n【异常信息】:\'SYSDATETIME\' 不是可以识别的 内置函数名称。\r\n【堆栈调用】: at NLite.Data.Common.ExecutionService.Query[T](QueryContext`1 q)\r\nat lambda_method(Closure )\r\nat NLite.Data.InternalDbContext.Execute(Expression expression)\r\nat NLite.Data.InternalDbContext.System.Linq.IQueryProvider.Execute[S](Expression expression)\r\nat System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source)\r\nat Ed.Dao.Impl.TPregnanterInfoDaoImpl.GetListByPage(Int32 pageIndex, Int32 pageSize, String selector, String predicate, String ordering, Int32& recordCount, Object[] values) in F:项目中心管理优创项目中心黄栾项目管理雪绒花项目项目源程序srcEd.DaoImplTPregnanterInfoDaoImpl.cs:line 350\r\nat Ed.Service.Impl.PregnanterInfoServiceImpl.GetPregnanterInfoList(Int32 pageIndex, Int32 pageSize, String selector, String predicate, String ordering, Int32& recordCount, Object[] values) in F:项目中心管理优创项目中心黄栾项目管理雪绒花项目项目源程序srcEd.ServiceImplPregnanterInfoServiceImpl.cs:line 137\r\n\r\n \r\n\r\n \r\n\r\n找到问题代码:\r\n\r\ncase \"Id\":\r\nint Id = int.Parse(value.ToString());\r\n\r\n//当前没有在服务时间内的记录\r\nvar currentStatus =\r\ndb.TPregnanterServiceRecords.Where(\r\nr =>\r\nr.PInfoCode == Id && r.PServiceBegin <= DateTime.Now &&\r\nr.PServiceEnd >= DateTime.Now)\r\n.OrderByDescending(r => r.PServiceBegin).ThenByDescending(r => r.PServiceEnd)\r\n.Select(r => r.PServiceType)\r\n.FirstOrDefault();\r\nresult.Add(\"CurrentStatus\", currentStatus);\r\nresult.Add(\"Id\", value);\r\nbreak;\r\n\r\n \r\n\r\n \r\n\r\n \r\n\r\n解决后的代码\r\n\r\ncase \"Id\":\r\nint Id = int.Parse(value.ToString());\r\n\r\n//当前没有在服务时间内的记录\r\n//var currentStatus =\r\n// db.TPregnanterServiceRecords.Where(\r\n// r =>\r\n// r.PInfoCode == Id && r.PServiceBegin <= DateTime.Now &&\r\n// r.PServiceEnd >= DateTime.Now)\r\n// .OrderByDescending(r => r.PServiceBegin).ThenByDescending(r => r.PServiceEnd)\r\n// .Select(r => r.PServiceType)\r\n// .FirstOrDefault();\r\n\r\n//SqlDateTime now = new SqlDateTime(DateTime.Now);\r\nvar currentStatusQuery =\r\ndb.TPregnanterServiceRecords\r\n.Where(\r\nr => r.PInfoCode == Id\r\n)\r\n.OrderByDescending(r => r.PServiceBegin)\r\n.ThenByDescending(r => r.PServiceEnd)\r\n.ToList();\r\n\r\nvar currentStatus = currentStatusQuery\r\n.Where(r =>\r\nr.PServiceBegin <= DateTime.Now &&\r\nr.PServiceEnd >= DateTime.Now\r\n)\r\n.Select(r => r.PServiceType).FirstOrDefault();\r\nresult.Add(\"CurrentStatus\", currentStatus);\r\nresult.Add(\"Id\", value);\r\nbreak;\r\ndefault:\r\nresult.Add(name, value);\r\nbreak;\r\n\r\n \r\n

    \r\n

    原因分析

    \r\nElinq在映射时间比较的时候适用的函数在SQL Server 2008时没有问题,但是SQL Server2005不支持。\r\n\r\n所以我就把数据库筛选语句去掉,改为在本地筛选,这样就可以了。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5600, '20141027104509', '20141027104509', '2014-10-27 02:45:11', '2019-03-25 21:29:22', '接收字符串之后trim和trimstart是个好习惯', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5601, 'java-again-learn-note-001-1-3-reliving-gui-hello-world', '重拾Java学习笔记001:【1.3】重温GUI形式的Hello world', '2012-10-28 00:26:56', '2019-03-25 21:29:22', 'import java.awt.*;\r\nimport java.awt.event.*;\r\nclass HelloWorld extends Frame\r\n{\r\npublic static void main(String args[])\r\n{\r\nHelloWorld Hello=new HelloWorld();\r\nLabel lbl=new Label(\"Hello World!\");\r\nHello.setTitle(\"Hello World\");\r\nHello.setSize(300,200);\r\nHello.setBackground(new Color(224,224,224));\r\nHello.add(lbl);\r\nlbl.setAlignment(1);\r\nlbl.setFont(new Font(\"Arial\",Font.PLAIN,24));\r\nHello.setLocation(260,180);\r\nHello.show();\r\nHello.addWindowListener(new WindowAdapter()\r\n{\r\n public void windowClosing(WindowEvent wet)\r\n {\r\n System.exit(0);\r\n }\r\n});\r\n}\r\n}', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5604, 'js-based-on-dates-of-birth-to-obtain-zodiac', 'js根据出生日期获取属相', '2014-10-29 08:25:43', '2019-03-25 21:29:22', '
    \r\n
    \r\n
      \r\n
    1. //根据生日获取属相
    2. \r\n
    3. function get_shuxiang_by_bir(bir) {
    4. \r\n
    5. var year = bir.split(\"-\")[0];
    6. \r\n
    7. var sxnames = [\"鼠\"\"牛\"\"虎\"\"兔\"\"龙\"\"蛇\"\"马\"\"羊\"\"猴\"\"鸡\"\"狗\"\"猪\"];
    8. \r\n
    9. var sx = year % 12 - 3;
    10. \r\n
    11. if (sx <= 0) {
    12. \r\n
    13. sx += 12;
    14. \r\n
    15. }
    16. \r\n
    17. //alert(sx);
    18. \r\n
    19. return \"属\" + sxnames[sx - 1];
    20. \r\n
    21. }
    22. \r\n
    \r\n
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5607, 'principle-and-realization-of-single-sign-on', '单点登录的原理及实现', '2014-10-29 11:03:52', '2019-03-25 21:29:22', '未完待续', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5609, 'talk-about-dynamic-linq-requires-attention-to-some-place', '说一说Dynamic LINQ需要注意的几个地方', '2014-10-29 12:04:33', '2019-03-25 21:29:22', '最近的项目用了LINQ,但是受限于LINQ的筛选条件,又不想因为使用SQL放弃跨数据库,最终使用了Dynamic LINQ。在实际的使用中,通过自己总结还是发现了不少需要注意的地方。\r\n\r\n下面是我写的构造筛选条件的函数,其中最需要之一的就是参数的类型问题,稍不注意就会遇到错误\r\n
    \r\n
    \r\n
      \r\n
    1. #region 构造动态LINQ查询条件 14-10-21 By 唐有炜
    2. \r\n
    3. \r\n
    4.      /// <summary>
    5. \r\n
    6.       /// 构造动态LINQ查询条件 14-10-21 By 唐有炜
    7. \r\n
    8.      /// </summary>
    9. \r\n
    10.       /// <param name=\"fields\">字段集合(id,name)</param>
    11. \r\n
    12.       /// <param name=\"eqs\">判断集合(=,>)</param>
    13. \r\n
    14.       /// <param name=\"values\">值集合(1,\"aaa\")【注意:数字型的字符串需要加s】</param>
    15. \r\n
    16.       /// <param name=\"operations\">条件集合(or,and)</param>
    17. \r\n
    18.       /// <returns>条件及参数集合</returns>
    19. \r\n
    20.      /// <returns></returns>
    21. \r\n
    22.       public static string BuildPredicate(string fields, string eqs, string values, string operations, out  object[] parms)
    23. \r\n
    24.       {
    25. \r\n
    26.           var fieldArray = Utils.StringToObjectArray(fields, \',\');
    27. \r\n
    28.           var eqArray = Utils.StringToObjectArray(eqs, \',\');
    29. \r\n
    30.           var valueArray = Utils.StringToObjectArray(values.ToString(), \',\');
    31. \r\n
    32.           var opArray = Utils.StringToObjectArray(operations, \',\');
    33. \r\n
    34. \r\n
    35.           string predicate = \"true\";
    36. \r\n
    37.           parms = new object[fieldArray.Length];
    38. \r\n
    39.           StringBuilder sb = new StringBuilder();
    40. \r\n
    41.           for (int i = 0; i < fieldArray.Length; i++)
    42. \r\n
    43.           {
    44. \r\n
    45.               //字段名称
    46. \r\n
    47.               var field = fieldArray[i].ToString();
    48. \r\n
    49.               //操作符(>,=,<,<>)
    50. \r\n
    51.               string eq = eqArray[i].ToString();
    52. \r\n
    53.               //字段值
    54. \r\n
    55.               object value = valueArray[i];
    56. \r\n
    57.               //与其他条件之间的逻辑关系(and,or)
    58. \r\n
    59.               var op = opArray[i].ToString();
    60. \r\n
    61. \r\n
    62.               //构造条件
    63. \r\n
    64.               var cond = field + eq + \"@\" + i;
    65. \r\n
    66.               if (eq.ToUpper() == \"LIKE\")
    67. \r\n
    68.               {
    69. \r\n
    70. \r\n
    71.                   cond = String.Concat(new[] {field, \".Contains(\"\"@\" + i, \") \"});
    72. \r\n
    73.               }
    74. \r\n
    75.               else
    76. \r\n
    77.               {
    78. \r\n
    79.                   //最后之前才加关系
    80. \r\n
    81.                   if (i < fieldArray.Length - 1) {
    82. \r\n
    83.                       cond = String.Concat(new[] { cond, \" \", op, \" \" });
    84. \r\n
    85.                   }
    86. \r\n
    87.               }
    88. \r\n
    89.                //累加条件
    90. \r\n
    91.               if (!String.IsNullOrEmpty(value.ToString()))
    92. \r\n
    93.               {
    94. \r\n
    95.                   sb.Append(cond);
    96. \r\n
    97.               }
    98. \r\n
    99. \r\n
    100.               //构造参数
    101. \r\n
    102.               if (!String.IsNullOrEmpty(value.ToString())) {
    103. \r\n
    104.                   if (Utils.IsNumeric(value))
    105. \r\n
    106.                   {
    107. \r\n
    108.                       parms[i] = int.Parse(value.ToString());
    109. \r\n
    110.                   }
    111. \r\n
    112.                   else
    113. \r\n
    114.                   {
    115. \r\n
    116.                       parms[i] = value;
    117. \r\n
    118.                   }
    119. \r\n
    120.               }else{
    121. \r\n
    122.                   parms[i] =0;
    123. \r\n
    124.               }
    125. \r\n
    126. \r\n
    127.           }
    128. \r\n
    129. \r\n
    130.           predicate = sb.ToString();
    131. \r\n
    132.           //修复末尾关系
    133. \r\n
    134.           if (predicate.Length>3&&(predicate.Substring(predicate.Length - 4, 3).ToUpper() == \"AND\"))
    135. \r\n
    136.           {
    137. \r\n
    138.               var end1 = predicate.Substring(predicate.Length - 4, 3).ToUpper();
    139. \r\n
    140.               if (end1 == \"AND\")
    141. \r\n
    142.               {
    143. \r\n
    144.                   predicate += \" true\";
    145. \r\n
    146.               }
    147. \r\n
    148. \r\n
    149.           }
    150. \r\n
    151.           if (predicate.Length > 2 && (predicate.Substring(predicate.Length - 3, 2).ToUpper() == \"OR\"))
    152. \r\n
    153.           {
    154. \r\n
    155.               var end2 = predicate.Substring(predicate.Length - 3, 2).ToUpper();
    156. \r\n
    157.               if ( end2 == \"OR\")
    158. \r\n
    159.               {
    160. \r\n
    161.                   predicate += \" true\";
    162. \r\n
    163.               }
    164. \r\n
    165. \r\n
    166.           }
    167. \r\n
    168. \r\n
    169. \r\n
    170.            return predicate;
    171. \r\n
    172.       }
    173. \r\n
    174. \r\n
    175.       #endregion
    176. \r\n
    \r\n
    \r\n\"QQ截图20141029200224\"\r\n\r\n最奇葩的就是当字符串为类似 “001”的时候会判别成int\r\n\r\n处理方法:\r\n\r\n待续', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5615, '20141030193203', '20141030193203', '2014-10-30 11:32:03', '2019-03-25 21:29:22', '去?留?', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5616, 'qq-sina-net-mvc-integration-account-internet', '.NET MVC集成QQ、新浪账号互联', '2014-10-31 04:09:12', '2019-03-25 21:29:22', '方式一:传统集成\r\n\r\nQQ\r\n\r\n \r\n\r\n \r\n\r\n \r\n\r\n \r\n\r\n方式二:使用MVC内置的账户接口(未完待续)', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5618, 'c-round-top-round-bottom-round', 'c# 四舍五入、上取整、下取整、百分比', '2014-10-31 06:00:08', '2019-03-25 21:29:22', '

    在处理一些数据时,我们希望能用“四舍五入”法实现,但是C#采用的是“四舍六入五成双”的方法,如下面的例子,就是用“四舍六入五成双”得到的结果:

    \r\n\r\n
    \r\n
    \r\n
    double d1 = Math.Round(1.25, 1);//1.2double d2 = Math.Round(1.24, 1);//1.2double d3 = Math.Round(1.26, 1);//1.3double d4 = Math.Round(1.35, 1);//1.4
    \r\n
    \r\n为了用C#来实现“四舍五入”,我写了下面的函数:\r\n
    \r\n
    \"复制代码\"
    \r\n\"\"代码\r\n
    \r\n
         ///<summary>/// 实现数据的四舍五入法\r\n   ///</summary>///<param name=\"v\">要进行处理的数据</param>///<param name=\"x\">保留的小数位数</param>///<returns>四舍五入后的结果</returns>    private double Round(double v, int x)\r\n    {\r\n        bool isNegative = false;\r\n        //如果是负数        if (v < 0)\r\n        {\r\n            isNegative = true;\r\n            v = -v;\r\n        }\r\n\r\n        int IValue = 1;\r\n        for (int i = 1; i <= x; i++)\r\n        {\r\n            IValue = IValue * 10;\r\n        }\r\n        double  Int = Math.Round(v * IValue + 0.5, 0);\r\n        v = Int / IValue;\r\n\r\n        if (isNegative)\r\n        {\r\n            v = -v;\r\n        }\r\n\r\n        return v;\r\n    }
    \r\n
    \r\n
    \"复制代码\"
    \r\n
    \r\n经过简单的测试,上面的函数能实现对数据的四舍五入法。\r\n\r\n \r\n\r\nMath.Round ()在四舍五入时有个问题:\r\n\r\nMath.Round(2.5,0) = 2;\r\n\r\nMath.Round(3.5,0) = 4;\r\n\r\n2.5应该等于3才对!\r\n\r\n在ASP中也存在这个问题,不过ASP中还有个FormatNumber可以用,但目前还不知道怎么使用?\r\n\r\n解释:\r\n\r\nMath.Round()准确的说,这个函数不是四舍五入,而是四舍六入五凑偶,就是说小于4或大于6的该舍该入是没有争议的,而5处在正中间,如果四舍五入则会造成数据的整体偏差,所以采取的原则是:如果舍入位为5,则舍入后最后一位为偶数,这是国际惯例。\r\n\r\n现在做的项目都要5入,解决方法:\r\n\r\n目前做法是:\r\n\r\n如:(3.45*10+0.5)取整,再除以10\r\n\r\nC# 中没有四舍五入函数,事实上我知道的程序语言都没有四舍五入函数,因为四舍五入算法不科学,国际通行的是 Banker 舍入法 Banker \'s rounding(银行家舍入)算法,即四舍六入五取偶。事实上这也是 IEEE 规定的舍入标准。因此所有符合 IEEE 标准的语言都应该是采用这一算法的\r\n\r\nMath.Round 方法默认的也是 Banker 舍入法 在 .NET 2.0 中 Math.Round 方法有几个重载方法\r\n\r\nMath.Round(Decimal, MidpointRounding)\r\n\r\nMath.Round(Double, MidpointRounding)\r\n\r\nMath.Round(Decimal, Int32, MidpointRounding)\r\n\r\nMath.Round(Double, Int32, MidpointRounding)\r\n\r\n将小数值舍入到指定精度。MidpointRounding 参数,指定当一个值正好处于另两个数中间时如何舍入这个值\r\n\r\n该参数是个 MidpointRounding 枚举\r\n\r\n此枚举有两个成员:\r\n\r\nAwayFromZero 当一个数字是其他两个数字的中间值时,会将其舍入为两个值中绝对值较大的值。\r\n\r\nToEven 当一个数字是其他两个数字的中间值时,会将其舍入为最接近的偶数。\r\n\r\n所以,要实现四舍五入函数,对于正数,可以加一个 MidpointRounding.AwayFromZero 参数指定当一个数字是其他两个数字的中间值时其舍入为两个值中绝对值较大的值,例:\r\n\r\nMath.Round(3.45, 2, MidpointRounding.AwayFromZero)\r\n\r\n不过对于负数上面的方法就又不对了\r\n\r\n因此需要自己写个函数来处理\r\n\r\ndouble ChinaRound(double valueint decimals)\r\n{\r\n  if (value < 0)\r\n{\r\n    return Math.Round(value + 5 / Math.Pow(10, decimals + 1), decimals, MidpointRounding.AwayFromZero);\r\n}\r\n  else\r\n{\r\n    return Math.Round(value, decimals, MidpointRounding.AwayFromZero);\r\n}\r\n}\r\n\r\n有些时候不一定要用四舍五入的,可能需要上取整或下取整:\r\n\r\nMath.Ceiling()和Math.Floor\r\n\r\nMath.Ceiling(3.1)=4;\r\nMath.Floor(3.9)=3;\r\n\r\n取天板值与地板值,与\"四舍五入\"无关。其实Floor的结果与(int)相同,因此也可以这样写Math.Floor((double)2/3+0.5)\r\n\r\nfloor 和 ceil是math unit 里的函数,使用前要先 Uses Math。\r\n\r\ntrunc 和 round 是system unit 里的函数,缺省就可以用。\r\n\r\nfloor 直接往小的取,比如 floor(-123.55)=-124,floor(123.55)=123\r\n\r\ntrunc 直接切下整数,比如 trunc(-123.55)=-123, floor(123.55)=123\r\n\r\nceil 直接往大的取,比如 ceil(-123.55)=-123, ceil(123.55)=124\r\n\r\nround 计算四舍五入,比如 round(-123.55)=-124,round(123.55)=124\r\n\r\nC#取整函数向上取整实例\r\n\r\nint a = 5;\r\n\r\nint b = 2;\r\n\r\nlbl.Text = Convert.ToString(Math.Ceiling((double)a / (double)b));\r\n\r\n \r\n\r\n百分比\r\n\r\n//var pInfoCertDegree = Math.Round((double)(Model.PInfoCert.Split(\',\').Length)/(double)9,2);\r\nvar pInfoCertDegree = Math.Round((double)(Model.PInfoCert.Split(\',\').Length) / (double)9, 2).ToString(\"P0\");\r\n\r\n
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5623, 'iquerable-convert-dynamic', 'Iquerable转换为Dynamic', '2014-10-31 07:54:56', '2019-03-25 21:29:22', '\"QQ截图20141031155135\"', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5626, 'net-log4net-logging-framework-summary', '【精华】.NET日志记录框架Log4Net使用总结', '2014-10-31 10:22:14', '2019-03-25 21:29:22', '
    \r\n需求背景\r\n=======\r\n做项目,记录日志是免不了的。在开发过程中还可以调试,但是在项目发布之后,不可能长期这么做,日志则能够在最快的时间内发现问题。最近,在好几个项目中使用了Log4net,感觉确实给我省了不少力,总结一下使用吧,同时也留作以后备用。\r\n\r\nLog4Net的使用\r\n=============\r\n1 使用Nuget安装Log4Net\r\n----------------------\r\n\r\n<span style="color: #008000">**Install-Package log4net**</span>\r\n\r\n[![QQ截图20141031182038](http://bcs.duapp.com/terwer/blog/2014/10/QQ截图20141031182038.png)](http://bcs.duapp.com/terwer/blog/2014/10/QQ截图20141031182038.png)\r\n\r\n[![QQ截图20141031182104](http://bcs.duapp.com/terwer/blog/2014/10/QQ截图20141031182104.png)](http://bcs.duapp.com/terwer/blog/2014/10/QQ截图20141031182104.png)\r\n\r\n2 创建LogHelper.cs\r\n------------------\r\n```cs\r\nusing System;\r\nnamespace UCsoft.Web.Common\r\n{\r\n    /// <summary>\r\n    /// Log4Net日志封装类  2014-08-28 14:58:50 By 唐有炜\r\n    /// </summary>\r\n    public class LogHelper\r\n    {\r\n        /// <summary>\r\n        /// 信息标志\r\n        /// </summary>\r\n        private static readonly log4net.ILog loginfo = log4net.LogManager.GetLogger("loginfo");\r\n        /// <summary>\r\n        /// 错误标志\r\n        /// </summary>\r\n        private static readonly log4net.ILog logerror = log4net.LogManager.GetLogger("logerror");\r\n        /// <summary>\r\n        /// 调试标志\r\n        /// </summary>\r\n        private static readonly log4net.ILog logdebug = log4net.LogManager.GetLogger("logdebug");\r\n        /// <summary>\r\n        /// Log4Net信息记录封装  2014-08-28 14:58:50 By 唐有炜\r\n        /// </summary>\r\n        ///\r\n        ///\r\n        public static void Info(string message)\r\n        {\r\n            if (loginfo.IsInfoEnabled)\r\n            {\r\n                loginfo.Info(message);\r\n            }\r\n        }\r\n        /// <summary>\r\n        /// Log4Net错误记录封装  2014-08-28 14:58:50 By 唐有炜\r\n        /// </summary>\r\n        ///\r\n        ///\r\n        public static void Error(string message)\r\n        {\r\n            if (logerror.IsErrorEnabled)\r\n            {\r\n                logerror.Error(message);\r\n            }\r\n        }\r\n        /// <summary>\r\n        /// Log4Net错误记录封装  2014-08-28 14:58:50 By 唐有炜\r\n        /// </summary>\r\n        ///\r\n        ///\r\n        ///\r\n        public static void Error(string message, Exception ex)\r\n        {\r\n            if (logerror.IsErrorEnabled)\r\n            {\r\n                if (!string.IsNullOrEmpty(message) &#038;&amp; ex == null)\r\n                {\r\n                    logerror.ErrorFormat("<br />【附加信息】 : {0}<br />", new object[] {message});\r\n                }\r\n                else if (!string.IsNullOrEmpty(message) &#038;&amp; ex != null)\r\n                {\r\n                    string errorMsg = BeautyErrorMsg(ex);\r\n                    logerror.ErrorFormat("<br />【附加信息】 : {0}<br />{1}", new object[] { message, errorMsg });\r\n                }\r\n                else if (string.IsNullOrEmpty(message) &#038;&amp; ex != null)\r\n                {\r\n                    string errorMsg = BeautyErrorMsg(ex);\r\n                    logerror.Error(errorMsg);\r\n                }\r\n            }\r\n        }\r\n        /// <summary>\r\n        /// Log4Net调试记录封装  2014-08-28 14:58:50 By 唐有炜\r\n        /// </summary>\r\n        ///\r\n        ///\r\n        public static void Debug(string message)\r\n        {\r\n            if (logdebug.IsErrorEnabled)\r\n            {\r\n                logdebug.Debug(message);\r\n            }\r\n        }\r\n        /// <summary>\r\n        /// Log4Net调试记录封装  2014-08-28 14:58:50 By 唐有炜\r\n        /// </summary>\r\n        ///\r\n        ///\r\n        ///\r\n        public static void Debug(string message, Exception ex)\r\n        {\r\n            if (logdebug.IsDebugEnabled)\r\n            {\r\n                if (!string.IsNullOrEmpty(message) &#038;&amp; ex == null)\r\n                {\r\n                    logdebug.DebugFormat("<br />【附加信息】 : {0}<br />", new object[] {message});\r\n                }\r\n                else if (!string.IsNullOrEmpty(message) &#038;&amp; ex != null)\r\n                {\r\n                    string errorMsg = BeautyErrorMsg(ex);\r\n                    logdebug.DebugFormat("<br />【附加信息】 : {0}<br />{1}", new object[] { message, errorMsg });\r\n                }\r\n                else if (string.IsNullOrEmpty(message) &#038;&amp; ex != null)\r\n                {\r\n                    string errorMsg = BeautyErrorMsg(ex);\r\n                    logdebug.Debug(errorMsg);\r\n                }\r\n            }\r\n        }\r\n        /// <summary>\r\n        /// 美化错误信息\r\n        /// </summary>\r\n        /// 异常\r\n        /// 错误信息\r\n        private static string BeautyErrorMsg(Exception ex)\r\n        {\r\n            string errorMsg = string.Format("【异常类型】:{0} <br />【异常信息】:{1} <br />【堆栈调用】:{2}",\r\n                new object[] {ex.GetType().Name, ex.Message, ex.StackTrace});\r\n            errorMsg = errorMsg.Replace("rn", "<br />");\r\n            errorMsg = errorMsg.Replace("位置", "<strong style="color:red">位置</strong><br />");\r\n            return errorMsg;\r\n        }\r\n    }\r\n}\r\n```\r\n\r\n<span style="color: #000000">3 </span><span style="color: #ff0000">在AssemblyInfo里面注册(非常重要)</span>\r\n-----------------------------------------------------------------------------------------------------------------\r\n\r\n[![QQ截图20141031182845](http://bcs.duapp.com/terwer/blog/2014/10/QQ截图20141031182845.png)](http://bcs.duapp.com/terwer/blog/2014/10/QQ截图20141031182845.png)\r\n\r\n[![QQ截图20141031182858](http://bcs.duapp.com/terwer/blog/2014/10/QQ截图20141031182858.png)](http://bcs.duapp.com/terwer/blog/2014/10/QQ截图20141031182858.png)\r\n\r\n```[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", ConfigFileExtension = "config", Watch = true)]```\r\n\r\n4 创建log4net.config\r\n---------------------\r\n```xml\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n```\r\n\r\n<span style="color: #ff0000">** 然后必须设置为复制到输出目录**</span>\r\n\r\n[![QQ截图20141031185734](http://bcs.duapp.com/terwer/blog/2014/10/QQ截图20141031185734.png)](http://bcs.duapp.com/terwer/blog/2014/10/QQ截图20141031185734.png)\r\n\r\n5 测试\r\n------\r\n\r\n```LogHelper.Debug("测试");```\r\n\r\n然后在Web根目录会生成一个Log文件夹,里面会有两个文件,一个一日期命名,一个错误文件\r\n\r\n[![QQ截图20141031190317](http://bcs.duapp.com/terwer/blog/2014/10/QQ截图20141031190317.png)](http://bcs.duapp.com/terwer/blog/2014/10/QQ截图20141031190317.png)\r\n\r\n[![QQ截图20141031190211](http://bcs.duapp.com/terwer/blog/2014/10/QQ截图20141031190211.png)](http://bcs.duapp.com/terwer/blog/2014/10/QQ截图20141031190211.png)\r\n\r\n\r\n
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5651, 'java-again-learn-note-001-1-4-java-basic-data-type', '重拾Java学习笔记001:【1.4】Java基本数据类型', '2012-11-02 07:44:03', '2019-03-25 21:29:22', '1 整型\r\n\r\nbyte 1个字节 -128-127\r\n\r\nshort 2个字节\r\n\r\nint 4个字节\r\n\r\nlong 8 个字节\r\n\r\n \r\n\r\n2', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5655, '%e8%af%a6%e8%a7%a3java%e6%8e%a5%e5%8f%a3%e6%8a%bd%e8%b1%a1%e7%b1%bb%ef%bc%8c%e5%86%85%e9%83%a8%e7%b1%bb', '详解Java接口,抽象类,内部类', '2014-11-02 11:22:31', '2019-03-25 21:29:22', 'http://bbs.csdn.net/topics/330148155', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5660, 'date-comparison', 'ddd', '2014-11-03 07:03:59', '2019-03-25 21:29:22', 'ccc', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5664, 'eclipse-shortcut-summary', 'eclipse快捷键总结', '2014-11-03 07:18:53', '2019-03-25 21:29:22', 'Ctrl+1 快速修复(最经典的快捷键,就不用多说了)\r\nCtrl+D: 删除当前行\r\nCtrl+Alt+↓ 复制当前行到下一行(复制增加)\r\nCtrl+Alt+↑ 复制当前行到上一行(复制增加)\r\nAlt+↓ 当前行和下面一行交互位置(特别实用,可以省去先剪切,再粘贴了)\r\nAlt+↑ 当前行和上面一行交互位置(同上)\r\nAlt+← 前一个编辑的页面\r\nAlt+→ 下一个编辑的页面(当然是针对上面那条来说了)\r\nAlt+Enter 显示当前选择资源(工程,or 文件 or文件)的属性\r\nShift+Enter 在当前行的下一行插入空行(这时鼠标可以在当前行的任一位置,不一定是最后)\r\nShift+Ctrl+Enter 在当前行插入空行(原理同上条)\r\nCtrl+Q 定位到最后编辑的地方\r\nCtrl+L 定位在某行 (对于程序超过100的人就有福音了)\r\nCtrl+M 最大化当前的Edit或View (再按则反之)\r\nCtrl+/ 注释当前行,再按则取消注释\r\nCtrl+O 快速显示 OutLine\r\nCtrl+T 快速显示当前类的继承结构\r\nCtrl+W 关闭当前Editer\r\nCtrl+K 参照选中的Word快速定位到下一个\r\nCtrl+E 快速显示当前Editer的下拉列表(如果当前页面没有显示的用黑体表示)\r\nCtrl+/(小键盘) 折叠当前类中的所有代码\r\nCtrl+×(小键盘) 展开当前类中的所有代码\r\nCtrl+Space 代码助手完成一些代码的插入(但一般和输入法有冲突,可以修改输入法的热键,也可以暂用Alt+/来代替)\r\nCtrl+Shift+E 显示管理当前打开的所有的View的管理器(可以选择关闭,激活等操作)\r\nCtrl+J 正向增量查找(按下Ctrl+J后,你所输入的每个字母编辑器都提供快速匹配定位到某个单词,如果没有,则在stutes line中显示没有找到了,查一个单词时,特别实用,这个功能Idea两年前就有了)\r\nCtrl+Shift+J 反向增量查找(和上条相同,只不过是从后往前查)\r\nCtrl+Shift+F4 关闭所有打开的Editer\r\nCtrl+Shift+X 把当前选中的文本全部变味小写\r\nCtrl+Shift+Y 把当前选中的文本全部变为小写\r\nCtrl+Shift+F 格式化当前代码\r\nCtrl+Shift+P 定位到对于的匹配符(譬如{}) (从前面定位后面时,光标要在匹配符里面,后面到前面,则反之)\r\n\r\n下面的快捷键是重构里面常用的,本人就自己喜欢且常用的整理一下(注:一般重构的快捷键都是Alt+Shift开头的了)\r\nAlt+Shift+R 重命名 (是我自己最爱用的一个了,尤其是变量和类的Rename,比手工方法能节省很多劳动力)\r\nAlt+Shift+M 抽取方法 (这是重构里面最常用的方法之一了,尤其是对一大堆泥团代码有用)\r\nAlt+Shift+C 修改函数结构(比较实用,有N个函数调用了这个方法,修改一次搞定)\r\nAlt+Shift+L 抽取本地变量( 可以直接把一些魔法数字和字符串抽取成一个变量,尤其是多处调用的时候)\r\nAlt+Shift+F 把Class中的local变量变为field变量 (比较实用的功能)\r\nAlt+Shift+I 合并变量(可能这样说有点不妥Inline)\r\nAlt+Shift+V 移动函数和变量(不怎么常用)\r\nAlt+Shift+Z 重构的后悔药(Undo)\r\n\r\n编辑\r\n作用域 功能 快捷键\r\n全局 查找并替换 Ctrl+F\r\n文本编辑器 查找上一个 Ctrl+Shift+K\r\n文本编辑器 查找下一个 Ctrl+K\r\n全局 撤销 Ctrl+Z\r\n全局 复制 Ctrl+C\r\n全局 恢复上一个选择 Alt+Shift+↓\r\n全局 剪切 Ctrl+X\r\n全局 快速修正 Ctrl1+1\r\n全局 内容辅助 Alt+/\r\n全局 全部选中 Ctrl+A\r\n全局 删除 Delete\r\n全局 上下文信息 Alt+?\r\nAlt+Shift+?\r\nCtrl+Shift+Space\r\nJava编辑器 显示工具提示描述 F2\r\nJava编辑器 选择封装元素 Alt+Shift+↑\r\nJava编辑器 选择上一个元素 Alt+Shift+←\r\nJava编辑器 选择下一个元素 Alt+Shift+→\r\n文本编辑器 增量查找 Ctrl+J\r\n文本编辑器 增量逆向查找 Ctrl+Shift+J\r\n全局 粘贴 Ctrl+V\r\n全局 重做 Ctrl+Y\r\n\r\n\r\n查看\r\n作用域 功能 快捷键\r\n全局 放大 Ctrl+=\r\n全局 缩小 Ctrl+-\r\n\r\n\r\n窗口\r\n作用域 功能 快捷键\r\n全局 激活编辑器 F12\r\n全局 切换编辑器 Ctrl+Shift+W\r\n全局 上一个编辑器 Ctrl+Shift+F6\r\n全局 上一个视图 Ctrl+Shift+F7\r\n全局 上一个透视图 Ctrl+Shift+F8\r\n全局 下一个编辑器 Ctrl+F6\r\n全局 下一个视图 Ctrl+F7\r\n全局 下一个透视图 Ctrl+F8\r\n文本编辑器 显示标尺上下文菜单 Ctrl+W\r\n全局 显示视图菜单 Ctrl+F10\r\n全局 显示系统菜单 Alt+-\r\n\r\n\r\n导航\r\n作用域 功能 快捷键\r\nJava编辑器 打开结构 Ctrl+F3\r\n全局 打开类型 Ctrl+Shift+T\r\n全局 打开类型层次结构 F4\r\n全局 打开声明 F3\r\n全局 打开外部javadoc Shift+F2\r\n全局 打开资源 Ctrl+Shift+R\r\n全局 后退历史记录 Alt+←\r\n全局 前进历史记录 Alt+→\r\n全局 上一个 Ctrl+,\r\n全局 下一个 Ctrl+.\r\nJava编辑器 显示大纲 Ctrl+O\r\n全局 在层次结构中打开类型 Ctrl+Shift+H\r\n全局 转至匹配的括号 Ctrl+Shift+P\r\n全局 转至上一个编辑位置 Ctrl+Q\r\nJava编辑器 转至上一个成员 Ctrl+Shift+↑\r\nJava编辑器 转至下一个成员 Ctrl+Shift+↓\r\n文本编辑器 转至行 Ctrl+L\r\n\r\n\r\n搜索\r\n作用域 功能 快捷键\r\n全局 出现在文件中 Ctrl+Shift+U\r\n全局 打开搜索对话框 Ctrl+H\r\n全局 工作区中的声明 Ctrl+G\r\n全局 工作区中的引用 Ctrl+Shift+G\r\n\r\n\r\n文本编辑\r\n作用域 功能 快捷键\r\n文本编辑器 改写切换 Insert\r\n文本编辑器 上滚行 Ctrl+↑\r\n文本编辑器 下滚行 Ctrl+↓\r\n\r\n\r\n文件\r\n作用域 功能 快捷键\r\n全局 保存 Ctrl+X\r\nCtrl+S\r\n全局 打印 Ctrl+P\r\n全局 关闭 Ctrl+F4\r\n全局 全部保存 Ctrl+Shift+S\r\n全局 全部关闭 Ctrl+Shift+F4\r\n全局 属性 Alt+Enter\r\n全局 新建 Ctrl+N\r\n\r\n\r\n项目\r\n作用域 功能 快捷键\r\n全局 全部构建 Ctrl+B\r\n\r\n\r\n源代码\r\n作用域 功能 快捷键\r\nJava编辑器 格式化 Ctrl+Shift+F\r\nJava编辑器 取消注释 Ctrl+\r\nJava编辑器 注释 Ctrl+/\r\nJava编辑器 添加导入 Ctrl+Shift+M\r\nJava编辑器 组织导入 Ctrl+Shift+O\r\nJava编辑器 使用try/catch块来包围 未设置,太常用了,所以在这里列出,建议自己设置。\r\n也可以使用Ctrl+1自动修正。\r\n\r\n\r\n运行\r\n作用域 功能 快捷键\r\n全局 单步返回 F7\r\n全局 单步跳过 F6\r\n全局 单步跳入 F5\r\n全局 单步跳入选择 Ctrl+F5\r\n全局 调试上次启动 F11\r\n全局 继续 F8\r\n全局 使用过滤器单步执行 Shift+F5\r\n全局 添加/去除断点 Ctrl+Shift+B\r\n全局 显示 Ctrl+D\r\n全局 运行上次启动 Ctrl+F11\r\n全局 运行至行 Ctrl+R\r\n全局 执行 Ctrl+U\r\n\r\n\r\n重构\r\n作用域 功能 快捷键\r\n全局 撤销重构 Alt+Shift+Z\r\n全局 抽取方法 Alt+Shift+M\r\n全局 抽取局部变量 Alt+Shift+L\r\n全局 内联 Alt+Shift+I\r\n全局 移动 Alt+Shift+V\r\n全局 重命名 Alt+Shift+R\r\n全局 重做 Alt+Shift+Y\r\n\r\n参考\r\nhttp://www.blogjava.net/action/articles/17339.html', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5668, 'net-mvc-uses-ajaxpager-to-implement-asynchronous-pages', '.NET MVC使用AjaxPager实现异步分页', '2014-11-04 03:30:25', '2019-03-25 21:29:22', '1 首先需要引用Mvcpager.dll,下载地址:http://www.webdiyer.com/downloads/\r\n\r\n\"QQ截图20141104113027\"\r\n\r\n2 未完待续\r\n\r\n【注意事项】:\r\n\r\n@Ajax.Pager(Model, new PagerOptions { PageIndexParameterName = \"pageIndex\", ShowPageIndexBox = true, PageIndexBoxType = PageIndexBoxType.DropDownList, ShowGoButton = false }, new MvcAjaxOptions { UpdateTargetId = \"re_neirong\", LoadingElementId = \"loadingDiv\", OnBegin = \"$(\'#re_neirong\').fadeOut(\'slow\')\", OnComplete = \"$(\'#re_neirong\').fadeIn(\'slow\')\" })、\r\n\r\n这里面的参数一定要一一对应。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5674, 'clever-use-of-unobtrusive-ajax-in-asp-net-mvc', 'ASP.NET MVC中Unobtrusive Ajax的妙用', '2014-11-04 04:01:45', '2019-03-25 21:29:22', '

    Unobtrusive Javascript有三层含义:一是在HTML代码中不会随意的插入Javsscript代码,只在标签中加一些额外的属性值,然后被引用的脚本文件识别和处理;二是通过脚本文件所增加的功能是一种渐进式的增强,当客户端不支持或禁用了Javsscript时网页所提供的功能仍然能够实现,只是用户体验会降低;三是能够兼容不同的浏览器。

    \r\n

    启用Unobtrusive Javascript的步骤:

    \r\n

    1.在web.config文件中加入

    \r\n\r\n
    \r\n
    <configuration>\r\n  <appSettings>\r\n    <add key=\"ClientValidationEnabled\" value=\"true\"/>\r\n    <add key=\"UnobtrusiveJavaScriptEnabled\" value=\"true\"/>\r\n  </appSettings>
    \r\n
    \r\n

    2.在网页中加入

    \r\n\r\n
    \r\n
    <script src=\"@Url.Content(\"~/Scripts/jquery-1.6.2.min.js\")\" type=\"text/javascript\"></script>\r\n<script src=\"@Url.Content(\"~/Scripts/jquery.unobtrusive-ajax.js\")\" type=\"text/javascript\"></script>\r\n<script src=\"@Url.Content(\"~/Scripts/jquery.validate.min.js\")\" type=\"text/javascript\"></script>\r\n<script src=\"@Url.Content(\"~/Scripts/jquery.validate.unobtrusive.min.js\")\" type=\"text/javascript\"></script>
    \r\n
    \r\n

    使用Unobtrusive Ajax主要有两个用途:做客户端的输入验证和异步的表单提交。客户端验证基本上是自动的,不用做特别的处理。下面用一个例子重点说一下提交表单。

    \r\n

    数据模型是这样的:每个类别有很多属性,属性可以分组,属性组可以嵌套。然后在网页创建和编辑属性组,示意图如下:

    \r\n

    \"\"

    \r\n

    这是我半年前写的代码:

    \r\n\r\n
    \r\n
    \"复制代码\"
    \r\n
            $(this).find(\".CreatePropertyGroup\").click(function () {\r\n            $(\".InputGroupName\").hide();\r\n            var id = $(this).next().val();\r\n            var td = $(this).parent().parent();\r\n            $.post(\"/Category/CreatePropertyGroup\", { parentId: id, name: $(this).prev().val() }, function () {\r\n                td.load(\"/Category/PropertyGroup\", { \"id\": id, \"resultType\": \"html\" }, loadGroupReady);\r\n            });\r\n        });
    \r\n
    \"复制代码\"
    \r\n
    \r\n
    \r\n
    \"复制代码\"
    \r\n
            $(this).find(\".CreateProperty\").click(function () {\r\n            $(\".InputPropertyName\").hide();\r\n            var id = $(this).next().val();\r\n            var name = $(this).parent().find(\".PropertyName\").val();\r\n            var type = $(this).parent().find(\"#PropertyDataType\").val();\r\n            var unit = $(this).parent().find(\".PropertyUnit\").val();\r\n            var range = $(this).parent().find(\".ValueRange\").val();\r\n            var td = $(this).parent().parent();\r\n            $.post(\"/Category/CreateProperty\", { groupId: id, name: name, type: type, unit: unit, range: range }, function () {\r\n                td.load(\"/Category/PropertyGroup\", { \"id\": id, \"resultType\": \"html\" }, loadGroupReady);\r\n            });\r\n        });
    \r\n
    \"复制代码\"
    \r\n
    \r\n

    完全使用jQuery获取控件值和提交,可读性和可维护性不是很好。现在改用Ajax.BeginForm之后,很大地简化了编程:

    \r\n\r\n
    \r\n
    \"复制代码\"
    \r\n
        <div class=\"InputGroupName\" style=\"display: none\">\r\n        @using (Ajax.BeginForm(new AjaxOptions { Url = Url.Action(\"CreatePropertyGroup\"), UpdateTargetId = \"PropertyGroup\" }))\r\n        {\r\n            <span>属性组名称:</span>\r\n            <input name=\"name\" class=\"GroupName\" type=\"text\" />\r\n            <input type=\"hidden\" name=\"categoryId\" value=\"@categoryId\" />\r\n            <input type=\"hidden\" name=\"path\" value=\"@path\" />\r\n            <input type=\"submit\" value=\"确定\" />\r\n        }\r\n    </div>
    \r\n
    \"复制代码\"
    \r\n
    \r\n

    对于不使用的表单的,直接点链接的可以用Ajax.ActionLink:

    \r\n\r\n
    \r\n
    \"复制代码\"
    \r\n
       <td>\r\n       @Ajax.ActionLink(\"删除\", \"DeletePropertyGroup\", new { categoryId = categoryId, path = path, name = property.Name },\r\n       new AjaxOptions\r\n       {\r\n           HttpMethod = \"Post\",\r\n           Url = Url.Action(\"DeletePropertyGroup\", new { categoryId = categoryId, path = path, name = property.Name }),\r\n           Confirm = \"确认要删除 \'\" + property.Name + \"\' 及其所有属性吗?\",\r\n           UpdateTargetId = \"PropertyGroup\"\r\n       })\r\n   </td>
    \r\n
    \"复制代码\"
    \r\n
    \r\n

    最终运行后生成的代码如下:

    \r\n\r\n
    \r\n
    \"复制代码\"
    \r\n
    <form action=\"/Category/EditCategory/4-2-2\" data-ajax=\"true\" data-ajax-mode=\"replace\"\r\n data-ajax-update=\"#PropertyGroup\" data-ajax-url=\"/Category/CreatePropertyGroup\" id=\"form5\" method=\"post\">\r\n            <span>属性组名称:</span>\r\n            <input name=\"name\" class=\"GroupName\" type=\"text\" />\r\n            <input type=\"hidden\" name=\"categoryId\" value=\"4-2\" />\r\n            <input type=\"hidden\" name=\"path\" value=\"PG.Props.1.Props\" />\r\n            <input type=\"submit\" value=\"确定\" />\r\n</form>
    \r\n
    \"复制代码\"
    \r\n
    \r\n
    \r\n
    <a data-ajax=\"true\" data-ajax-confirm=\"确认要删除 &#39;外观特征&#39; 及其所有属性吗?\" data-ajax-method=\"Post\"\r\n data-ajax-mode=\"replace\" data-ajax-update=\"#PropertyGroup\" data-ajax-url=\"/Category/DeletePropertyGroup?categoryId=4-2&amp;path=PG.Props&amp;name=%E5%A4%96%E8%A7%82%E7%89%B9%E5%BE%81\"\r\n href=\"/Category/DeletePropertyGroup?categoryId=4-2&amp;path=PG.Props&amp;name=%E5%A4%96%E8%A7%82%E7%89%B9%E5%BE%81\">删除</a>
    \r\n
    \r\n

    可以看到魔力就在于以data-ajax开头的一些属性中,当Javascript被禁用后,表单仍能提交,链接也能点开,只不过不再是异步的了。

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5678, 'net-mvc-asynchronously-loads', '.NET MVC异步加载', '2014-11-04 07:05:41', '2019-03-25 21:29:22', '//搜索结果\r\nIQueryable<VPersonalResume> results = db.VPersonalResumes.Where(r => r.resume_state == \"true\");\r\n\r\n#region 判断是否是从企业中心跳转过来 141103 By 唐有炜\r\n\r\n//判断是否是从企业中心跳转过来\r\nvar from = Request.QueryString[\"from\"];\r\nif (!String.IsNullOrEmpty(from))\r\n{\r\nViewBag.From = from.ToString();\r\n}\r\n\r\n#endregion\r\n\r\n#region 保存登录状态\r\n\r\n//保存登录状态\r\nViewBag.IsLogin = (Session[UCKeys.SESSION_COMPANY_INFO_ID] != null).ToString().ToLower();\r\n\r\n#endregion\r\n\r\n#region 保存会员状态(free、outdate、pointZero、ok)\r\n\r\n//保存会员状态(free、outdate、pointZero、ok)\r\nvar payState = \"free\";\r\nif (bool.Parse(ViewBag.IsLogin))\r\n{\r\nvar cid = int.Parse(Session[UCKeys.SESSION_COMPANY_INFO_ID].ToString());\r\nusing (ZhaopinModels db2 = new ZhaopinModels())\r\n{\r\nvar pays =\r\ndb2.TCooperatePays.Where(c => c.pay_status == true).Where(c => c.company_id == cid).ToList();\r\n\r\nif (pays.Count == 0) //免费(最多只能看500份)\r\n{\r\nresults = results.Take(500);\r\npayState = \"free\";\r\n}\r\nelse //过期、点数\r\n{\r\nint points = 0;\r\nvar timeFlag = false;\r\n\r\nforeach (var coop in pays)\r\n{\r\npoints += (int) coop.resume_point;\r\n\r\n//只要有一个合作记录没有过期就可以\r\nif (DateTime.Compare(coop.pay_end.Value, DateTime.Now) > 0)\r\n{\r\ntimeFlag = true;\r\ncontinue;\r\n}\r\nelse\r\n{\r\ntimeFlag = false;\r\n}\r\n}\r\nif (points <= 0) //点数过期\r\n{\r\nresults = results.Take(500);\r\npayState = \"pointZero\";\r\n}\r\nelse if (!timeFlag)\r\n{\r\nresults = results.Take(500);\r\npayState = \"outdate\";\r\n}\r\nelse\r\n{\r\npayState = \"ok\";\r\n}\r\n\r\n//LogHelper.Debug(\"企业id为\"+cid+\"的点数:\" + points);\r\n}\r\n}\r\n}\r\nViewBag.PayState = payState;\r\n//LogHelper.Debug(\"当前状态:\" + ViewBag.PayState);\r\n\r\n#endregion\r\n\r\n#region 页码处理\r\n\r\nif (null == pageIndex)\r\n{\r\npageIndex = 1;\r\n}\r\n\r\n#endregion\r\n\r\n \r\n\r\n//结果筛选\r\nvar model = db.VPersonalResumes.OrderByDescending(r => r.account_regDate)\r\n.ToPagedList((int) pageIndex, 8);\r\nLogHelper.Debug(JsonConvert.SerializeObject(Request.IsAjaxRequest()));\r\nif (Request.IsAjaxRequest())\r\n{\r\nSystem.Threading.Thread.Sleep(2000);\r\nreturn PartialView(\"_AjaxLoading\", model);\r\n}\r\nreturn View(model);\r\n\r\n \r\n\r\n \r\n\r\n \r\n\r\n \r\n\r\n \r\n\r\n//异步填充数据 141104\r\nfunction fill_data() {\r\nvar data = $(\"#resumeSearchForm\").serialize();\r\n$.ajax({\r\ntype: \"POST\",\r\ncache: false,\r\nurl: \"/ResumeCenter/Index/page/4?X-Requested-With=XMLHttpRequestsss\",\r\ndata: data,\r\n//dataType: \"text/html\",\r\nbeforeSend: function () {\r\n$(\"#loadingDiv\").show();\r\n},\r\ncomplete: function () {\r\n//showMsg(\"数据加载完成!\");\r\n$(\"#loadingDiv\").hide();\r\n},\r\nsuccess: function (result) {\r\n//showMsg(\"数据加载成功!\");\r\n$(\"#re_neirong\").html(result);\r\n},\r\nerror: function() {\r\nshowMsg(\"网络连接错误!\");\r\n}\r\n});\r\n\r\n}', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5680, '20141104191418', '20141104191418', '2014-11-04 11:14:18', '2019-03-25 21:29:22', '我愿意为了用户体验放弃捷径。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5681, 'asp-net-web-api-%e4%b8%8e-andriod-%e6%8e%a5%e5%8f%a3%e5%af%b9%e6%8e%a5%e5%bc%80%e5%8f%91%e7%bb%8f%e9%aa%8c%ef%bc%8c%e7%bb%99%e5%b0%8f%e4%bc%99%e4%bc%b4%e5%88%86%e4%ba%ab%e4%b8%80%e4%b8%8b%ef%bc%81', 'Asp.Net Web Api 与 Andriod 接口对接开发经验,给小伙伴分享一下!', '2014-11-05 17:11:32', '2019-03-25 21:29:22', '博客园Asp.Net Web Api 与 Andriod 接口对接开发经验,给小伙伴分享一下!http://www.cnblogs.com/Kummy/p/3499759.html', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5684, 'installation-and-configuration-of-intel-atom-android-emulator', 'Intel Atom Android模拟器的安装与配置', '2014-11-06 02:29:15', '2019-03-25 21:29:22', '
    前言\r\n====\r\n\r\n大家现在开发使用的Android模拟器模拟的是 ARM的体系结构(arm-eabi),因此模拟器并不是运行在x86上而是模拟的ARM,所以我们调试程序的时候经常感觉到非常慢,大部分开发者应该都深有体会。\r\n\r\n针对这种情况,前段时间Intel推出了支持x86的Android模拟器,这将大大提高启动速度和程序的运行速度,这将允许Android模拟器能够以原始速度(真机运行速度)运行在使用Intel x86处理器的电脑中,各位开发者有福了,下面将为大家展示使用方法。\r\n\r\n一、首先下载intel提供的  Intel® Hardware Accelerated Execution Manager 1.0.1(R2)\r\n---------------------------------------------------------------------------------\r\n\r\n1.去Intel官网下载:[http://software.intel.com/en-us/articles/intel-hardware-accelerated-execution-manager/](http://software.intel.com/en-us/articles/intel-hardware-accelerated-execution-manager/)\r\n\r\n2.SDK Manager:展开至\r\nExtras->Intel Hardware Accelerated Execution Manager\r\n![Intel Hardware Accelerated Execution Manager ](http://bcs.duapp.com/terwer/blog/2015/02/2015-02-15_182848.png)\r\n\r\nrequirement:\r\n1). requires the Android* SDK to be installed (version 17(Android 4.2) or higher).\r\nSDK17(Android 4.2)或者以上\r\n2).Intel® processor with support for VT-x, EM64T, and Execute Disable (XD) Bit functionality         Intel的CPU:并支持VT-X(虚拟化技术)、可扩展64位、Execute Disable Bit。(均需要保证在BIOS中开启Enable)\r\n3). At least 1 GB of available RAM                                                                                        1G以上内存,否则安装不了\r\n\r\n满足硬件和软件要求之后,就可以开始安装了,一直下一步至安装成功。途中有个地方选择分配给HAXM内存大小,一般默认就好,分太多会拖慢整机速度。\r\n![分配给HAXM内存大小](http://bcs.duapp.com/terwer/blog/2015/02/2015-02-15_201849.png)\r\n\r\n安装成功后命令行输入```sc query intelhaxm```,查看运行状态:```state is: \"4 RUNNING\"``` ,即代表安装成功。\r\n![](http://bcs.duapp.com/terwer/blog/2015/02/2015-02-15_204817.png)\r\n需要更改分配内存,重新运行一下安装程序选择change即可修改。\r\n还可以使用以下指令手动开启和关闭:\r\nStop:\r\n```cmd\r\nsc stop intelhaxm\r\n```\r\n\r\nStart:\r\n```cmd\r\nsc start intelhaxm\r\n```\r\n\r\n满足软硬件条件,若提示如下 ```Error:but Intel Execute Disable Bit (XD) is not turned on......```\r\n![but Intel Execute Disable Bit (XD) is not turned on](http://bcs.duapp.com/terwer/blog/2015/02/2015-02-15_203635.png)\r\n(需要开启系统数据执行保护功能DEP,下午纠结了好久才查到。\r\n官网原文:[Windows* hosts may need to enable DEP (Data Execution Prevention) in addition to Intel XD)](https://software.intel.com/en-us/android/articles/installation-instructions-for-intel-hardware-accelerated-execution-manager-windows)\r\n命令行使用指令:```bcdedit.exe /set nx optin``` 打开即可,需要重启电脑\r\n\r\n二、下载Intel Atom x86 System Image\r\n====================================\r\n\r\n1. 从SDK Manager下载:打开SDK Manager,展开至Android4.4(API19),需要和4.4的SDK Platform配合使用。\r\n![Intel Atom x86 System Image](http://bcs.duapp.com/terwer/blog/2015/02/2015-02-15_205313.png)\r\nor从Intel官网下载:http://software.intel.com/en-us/android/\r\n\r\n2.使用AVD Manager创建一个新的AVD:Hardware Property里面选择GPU emulation  yes   还有  Keyboard  support  yes\r\n\r\n3.开始使用飞速的模拟器吧   
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5686, 'failed-to-allocate-memory8-andriod-simulator-cannot-start', 'Failed to allocate memory: 8 (andriod模拟器无法启动)', '2014-11-06 02:29:38', '2019-03-25 21:29:22', '

    今天因为项目需要要新建一个项目,但是模拟器创建成功却不能启动,仔细看了一下,有如下错误信息提示:

    \r\n

    [2013-05-21 15:23:43 - Emulator] Failed to allocate memory: 8\r\n[2013-05-21 15:23:43 - Emulator]\r\n[2013-05-21 15:23:43 - Emulator] This application has requested the Runtime to terminate it in an unusual way.\r\n[2013-05-21 15:23:43 - Emulator] Please contact the application\'s support team for more information.

    \r\n

    \r\n

    最后百度查询得知:模拟器无法启动的原因是电脑内存不足了,我们在新建模拟器的时候,默认会分配1024M(1G)的内存,因为我们的电脑本来就消耗了很大的内存了,所以无法再给模拟器分配1G的内存,导致模拟器无法启动,解决方式就是打开模拟器选择界面,选中无法启动的模拟器,点击右侧的“Edit”按钮,在弹出的编辑选项中,将“Memery Option”改为512M或者更低。

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5689, 'perfect-win8-acceleration-program-after-i-run-out-of-something-like-this-you-would-also-be-run-out-like-this', '完美Win8加速方案。我用完之后是这个样子,你们用完之后也会是这个样子!', '2014-11-06 03:24:39', '2019-03-25 21:29:22', '\r\n\r\n\r\n\r\n\r\n\r\n
    1.很多朋友win8运行慢就是因为没有安装驱动。虽然win8自带的驱动已经强大到不科学了。但是自带驱动往往有自己的瓶颈。难道自带驱动会自己切换么核心独立显卡么。这时候就需要大家自己找驱动了。\r\nAHCI驱动:这个是神器。用过的都知道,安装前后硬盘读写的速度差了可不是一星半点啊。拿我的本来说,安装前开机是1分30(没有开启混合启动),安装后开机速度顺利进入1min。所以只要你的电脑支持就果断安装它吧。检测有木有安装这个驱动的办法就是进入设备管理器。看是否是标准AHCI驱动。\r\n下载地址:http://pan.baidu.com/share/link?shareid=4027&uk=1091675953\r\n<ignore_js_op>\"未命名.jpg\" \r\n显卡驱动:这个就不多说了。\r\n现在最新的Nvidia独立显卡驱动是305.67_notebook_win8_winvista_win7_64bit_international\r\n核心显卡驱动是:http://downloadmirror.intel.com/21180/a08/win8_64_1528.zip\r\n2.系统优化,这个再说就要吐了。但对于新系统还是要老生常谈一下。\r\n首先关闭没用的特效。在这里给大家一个参考。个人感觉是性能与显示效果的一个平衡点。\r\n<ignore_js_op>\"未命名.jpg\" \r\n*禁用Themes服务。没有了Aero还留着这货干神马。关闭后不影响任务栏透明!\r\n*禁用系统还原。这个就不多说了。浪费资源啊。\r\n*(禁用win8休眠(快速启动)功能。这个就就智者见智了。我个人认为关了快速启动即可以省掉硬盘一块宝贵的空间。又可以延长机械硬盘寿命。关了就对了。管理员打开命令提示符输入powercfg /h off即可。重新启用的话把off改为on\r\n*像数字一类的优化软件本人一向是避之不及的。但这不代表没了数字就不优化系统了。在这里我推荐用魔方绿色版。用完即删。感觉非常好。\r\n*每次update完系统都清理下缓存的补丁文件。\r\n3.软件方面。鄙人没有太多的研究。但是推荐大家用独木成林(http://www.guofs.com/这个人做的精简版系列软件。去广告提高运行效率。也是非常爽的。杀毒软件我推荐avast!。如果您非想用软件商店里某数字杀毒我也不拦着。但是尽量不要用微软自带的杀毒。那货真的会占用成吨的资源。\r\n\r\n\r\n\r\n\r\n帖子就先写到这里。鼓捣系统的时候其实改了挺多的。一写帖子就想不起来了。等想起来再慢慢加。最后上一张自己用的软件。谢谢大家!\r\n<ignore_js_op>\"未命名.jpg\"
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5691, 'resolve-entity-type-ucsoft-entity-tcusbase-not-elinq-configure-mapping', '解决ELInq出现 Entity type 'UCsoft.Entity.TCusBase' not configure mapping!', '2014-11-06 06:49:10', '2019-03-25 21:29:22', '今天重新对项目结构进行了调整,却发现原来用的好好的ELINQ突然出现了下面的错误:\r\n\r\n异常时间:2014-11-06 14:20:19,354 [6] 
    异常级别:ERROR 
    日志标志:logerror 
    异常信息:
    【附加信息】 : 登陆错误
    【异常类型】:MappingException 
    【异常信息】:Entity type \'UCsoft.Entity.TCusBase\' not configure mapping! 
    【堆栈调用】: 在 NLite.Data.DbConfiguration.GetMapping(Type entityType)
    在 NLite.Data.DbContext.InitializeDbSets()
    在 NLite.Data.DbContext..ctor(DbConfiguration dbConfiguration)
    在 UCsoft.Data.UCDbContext..ctor() 位置
    e:MyWorkteaCRMV3srcUCsoft.DataUCDbContext.cs:行号 45
    在 UCsoft.Dao.Impl.TSysUserDaoImpl.ExistsEntity(Expression`1 predicate) 位置
    e:MyWorkteaCRMV3srcUCsoft.DaoImplTSysUserDaoImpl.cs:行号 505
    在 UCsoft.Service.Impl.AccountServiceImpl.UserNameExists(String accountType, String userName) 位置
    e:MyWorkteaCRMV3srcUCsoft.ServiceImplAccountServiceImpl.cs:行号 111
    在 UCsoft.Service.Impl.AccountServiceImpl.ValidateAccount(String type, String accountType, String userName, String userPassword) 位置
    e:MyWorkteaCRMV3srcUCsoft.ServiceImplAccountServiceImpl.cs:行号 58
    在 UCsoft.Service.Impl.AccountServiceImpl.Login(HttpContext httpContext, String type, String accountType, String userName, String userPassword, String remember, String clientIp, String clientPlace, String clientTime) 位置
    e:MyWorkteaCRMV3srcUCsoft.ServiceImplAccountServiceImpl.cs:行号 277 \r\n\r\n仔细回忆:想起来之前把Dbcontext和Entity放在一个程序集里面然后映射时调用的\r\n\r\n.AddFromAssemblyOf<UCDbContext>(t => t.HasAttribute<TableAttribute>(false))\r\n\r\n现在我把DbContext单独弄成了程序集,Entity分开了\r\n\r\n查看了ELINQ源码,通过验证发现确实是这个问题。\r\n\r\n现在调用\r\n\r\n .AddClass<TCusBase>()\r\n //.AddFromAssemblyOf<UCDbContext>(t => t.HasAttribute<TableAttribute>(false))\r\n\r\n可以解决\r\n\r\n改进方法\r\n\r\n不加载程序集,直接添加类的映射。改进后的代码:\r\n\r\n \r\n\r\n \r\n\r\n \r\n
    \r\n
    \r\n
      \r\n
    1. static UCDbContext()
    2. \r\n
    3.     {
    4. \r\n
    5.          dbConfiguration = DbConfiguration
    6. \r\n
    7.                  .Configure(connectionStringName)
    8. \r\n
    9.                  .SetSqlLogger(() =>SqlLog.Debug)
    10. \r\n
    11.                  //.AddFromAssemblyOf<UCDbContext>(t => t.HasAttribute<TableAttribute>(false))//当数据库操作上下文和实体类在同一个程序集里面时可以使用
    12. \r\n
    13.               ;
    14. \r\n
    15.            //循环添加映射
    16. \r\n
    17.         dbConfiguration = dbConfiguration.AddClass<TCusBase>();
    18. \r\n
    19.            //...
    20. \r\n
    21.     }
    22. \r\n
    \r\n
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5693, 'principle-and-realization-of-search-keywords-highlighting', '搜索关键词高亮的原理及实现', '2014-11-08 04:44:27', '2019-06-10 17:22:36', '原理:\r\n\r\n在搜索关键词高亮中一般的方法都是采用替换的办法(Replace)这个方法有一个缺点就是不能区分大小写的问题。在网上找了找发现有人用正则表达式的方法来解决这个问题还真不错,效率也比较高,归纳如下,有用得到的朋友可以一试。\r\n\r\n实现\r\n\r\njava版:\r\n1.搜索的高亮显示方法,采用java的String.repalceAll(oldString,newString);方法达到页面高亮显示的目的,原理就是给关键字加上+\"关键字\"+\r\n
    \r\n
    \r\n
      \r\n
    1. public String higiLight(String content,String regions,String persons,String companys)
    2. \r\n
    3. {
    4. \r\n
    5. String newregions=\"<span class=\"+\">\"+regions+\"</span>\";
    6. \r\n
    7. String newpersons=\"<span class=\"+\">\"+persons+\"</span>\";
    8. \r\n
    9. String newcompanys=\"<span class=\"+\">\"+companys+\"</span>\";
    10. \r\n
    11. content=content.replaceAll(regions, newregions);
    12. \r\n
    13. content=content.replace(persons, newpersons);
    14. \r\n
    15. content=content.replace(companys, newcompanys);
    16. \r\n
    17. return content;
    18. \r\n
    19. }
    20. \r\n
    \r\n
    \r\n2.通过Struts对象传值到前台,需要使用escape=\"false\"原理是:Struts2 数据标签要转义才能显示的HTML格式\r\n3.Struts截取字符串方式是 //从0-100截取字段,用jstl标签\r\nuri=\"http://java.sun.com/jsp/jstl/functions\" prefix=\"fn\" %>\r\n${fn:substring(\"name\"),beginIndex,endIndex}\r\nC#版:\r\n
    \r\n
    \r\n
      \r\n
    1. //搜索关键词高亮显示函数
    2. \r\n
    3.      public static string HighLightKeyWord(string pain,string keyword)
    4. \r\n
    5.      {
    6. \r\n
    7. \r\n
    8.          //搜索关键词高亮函数
    9. \r\n
    10.          System.Text.RegularExpressions.MatchCollection m = Regex.Matches(pain, keyword, RegexOptions.IgnoreCase);
    11. \r\n
    12.          //忽略大小写搜索字符串中的关键字
    13. \r\n
    14.          for (int j = 0; j < m.Count; j++)//循环在匹配的子串前后插东东
    15. \r\n
    16.          {
    17. \r\n
    18.              //j×31为插入html标签使pain字符串增加的长度:
    19. \r\n
    20.              pain = pain.Insert((m[j].Index + keyword.Length + j * 31), \"</font>\");//关键字后插入html标签
    21. \r\n
    22.              pain = pain.Insert((m[j].Index + j * 31), \"<font color=#ff0000>\");//关键字前插入html标签
    23. \r\n
    24.          }
    25. \r\n
    26. \r\n
    27.          //搜索关键词高亮函数By JN 2006.11.30
    28. \r\n
    29.          return pain;
    30. \r\n
    31.      }
    32. \r\n
    \r\n
    \r\n
    \r\n
    \r\n
      \r\n
    1. // 不区分大小写高亮的。
    2. \r\n
    3. static string HighlightKeyword(string str, string keyword)
    4. \r\n
    5. {
    6. \r\n
    7. int index;
    8. \r\n
    9. int startIndex = 0;
    10. \r\n
    11. string highlightBegin = \"<span style=\'background-color:#FFEE62\'>\";
    12. \r\n
    13. string highlightEnd = \"</span>\";
    14. \r\n
    15. int length = highlightBegin.Length + keyword.Length;
    16. \r\n
    17. int lengthHighlight = length + highlightEnd.Length;
    18. \r\n
    19. while ((index = str.IndexOf(keyword, startIndex, StringComparison.OrdinalIgnoreCase)) > -1)
    20. \r\n
    21. {
    22. \r\n
    23. str = str.Insert(index, highlightBegin).Insert(index + length, highlightEnd);
    24. \r\n
    25. startIndex = index + lengthHighlight;
    26. \r\n
    27. }
    28. \r\n
    29. return str;
    30. \r\n
    31. }
    32. \r\n
    \r\n
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5696, '20141108231400', '20141108231400', '2014-11-08 15:11:29', '2019-03-25 21:29:22', '\"image\"', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5699, 'restore-java-learning-notes-005-interpretation-of-object-classes-in-java', '重拾Java学习笔记005:解读Java中的Object类', '2012-11-08 16:33:10', '2019-03-25 21:29:22', 'java.lang.Object.clone()\r\n\r\n博客园java.lang.Object.clone()解读http://www.cnblogs.com/gw811/archive/2012/10/07/2712252.html', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5701, 'apache-harmony', 'Apache Harmony学习', '2012-11-09 15:16:10', '2019-03-26 00:29:36', 'Apache Harmony 是 2005 年 5 月宣布的开放源码 Java SE 实现,本文是由 5 部分组成的 进入 Harmony 世界系列文章的第一篇,这个系列主要介绍 Apache Harmony 项目的内部实现,最新发展现状和开源 Java 开发的模式,并鼓励和欢迎大家参与到 Harmony 的社区中来。本文是 5 个系列的第一篇,概括介绍了 Harmony 项目的背景,技术架构,社区运作和未来的方向。\r\n\r\n本文是 5 个系列的第一篇,概括介绍了 Harmony 项目的背景,技术架构,社区运作和未来的方向。\r\n\r\nApache Harmony 的背景\r\n\r\nApache Harmony 的提案在 2005 年 5 月被 Apache 软件基金会(ASF)接受,并且按照 ASF 惯例成为一个孵化器(incubator)项目。\r\n\r\nHarmony 为自己定了两个目标,首先是开发出一个独立并且与现有 JDK 兼容的 Java SE 5 实现,并且以 Apache 软件许可证 2.0 版发行;其次是建立一个开放的模块化运行时架构,包括虚拟机和类库之间及其内部的模块化,并通过这个平台,允许社区在此基础上自由定制自己的 Java 实现,或者对某个模块单独进行创新。\r\n\r\nApache Harmony 项目的成立以及它的这两个目标具有很大的现实意义。首先,由于商业JDK的流行性,它们几乎成为事实上的标准,所以 Harmony 必须与它们保持高度的兼容,才能够使应用程序的迁移成本最低,也就相对容易被用户所接受;其次,Harmony 存在的重要意义之一就在于这是一个属于开源社区的 Java 平台,在这个平台上,社区可以自由的移植和创新,而一个开放的模块化的架构,将为移植和创新带来最大的便利性;最后,Apache 软件许可证是一个对商业公司和开源社区都比较友好的开源许可证,因此 Harmony 可以给最大范围的开发人员和用户带来便利。本文和本系列后续文章将详细介绍 Harmony 在兼容性和模块化方面的努力,以及这些目标带来的价值。\r\n\r\n也许正是基于以上一些原因,Harmony 项目成立仅仅一年多一点的时间,就得到了广泛的支持和关注,并且得以飞速发展。目前,Apache Harmony 已经拥有了一个活跃的开发社区,并且接受了来自公司,学校和个人的多次捐赠。IBM 在 developerWorks 上提供了一个 Java 虚拟机环境的免费下载,以支持 Harmony 项目的开发,还多次捐赠了核心类库的实现和测试代码,在 IBM 英国 Hursley 软件开发实验室和中国软件开发中心各有一个开发团队积极参与 Harmony 项目。此外 Harmony 项目还接受了三个 Java 虚拟机实现的捐赠,另外还有一个开源 Java 虚拟机 SableVM 正在积极的与 Harmony 社区合作以实现与 Harmony 类库的集成。Java SE 实现难度最大的是其规模庞大的类库,而最近的类库 API 覆盖率统计表明,Harmony 的 J2SE 1.4.2 类库 API 的覆盖率已经超过 80%,Java SE 5 的覆盖率已经达到 79% 以上。目前经不完全测试,在 Harmony 上已经可以良好运行 Eclipse、JEdit、Ant 等流行的 Java 工具,并且可以部分运行 Tomcat 和 Geronimo 等企业应用。\r\n\r\n \r\n\r\n技术架构\r\n\r\n如前所述,Apache Harmony 非常注重模块化,从图一中,可以对 Apache Harmony 的总体架构有一个初步的感觉。与所有其他 Java SE 实现类似的是,Harmony 从大体上可以分为三个层次,最下层是操作系统,中间是 Java 虚拟机,最上层是 Java 类库。而 Harmony 的特点在于:\r\n\r\n虚拟机和类库内部被高度模块化,在 Harmony 中,类库在功能和 Java Package 的基础上被分成 31 个模块,而虚拟机也被分成即时编译器, 内存管理, 线程管理,Java 本地接口等等模块。每个模块都有一定的接口定义,从而有可能单独被替换成不同的实现。\r\n\r\n操作系统层次与虚拟机层次之间的接口由 Port Layer 定义。Port Layer 封装了不同的操作系统的差异,为虚拟机和类库的本地代码提供了一套统一的 API 访问底层系统调用。\r\n\r\n虚拟机与类库之间的接口除了 Java 规范定义的 JNI,JVMITI 之外,加入了一层虚拟机接口,主要由内核类(Kernel Class)和本地代码 VMI 组成,实现了虚拟机接口的虚拟机实现都可以使用 Harmony 的类库实现,并且可以被 Harmony 提供的同一个 Java 启动程序启动。\r\n\r\n图一 Apache Harmony 技术架构鸟瞰图\r\n\r\n \r\n\r\n本节将分别对 Port Layer,VMI 和 Java 统一启动程序作进一步的介绍。\r\n\r\nApache Harmony Port Layer\r\n\r\nApache Harmony 在操作系统与虚拟机之间定义了一个 Port Layer,Port Layer 是由一个标准 C 的库(Port Library)来实现得,Port Library 与操作系统交互,为虚拟机和类库的本地代码提供了一个平台无关的标准 C 语言 API 访问系统调用。诸如文件 I/O,网络 I/O, 内存操作,信号处理,以及错误处理等等功能,都被纳入 Port Library 的范围。\r\n\r\n通过使用 Port Library, 所有(目前还没有做到,但这是设计目标)与操作系统平台相关的内容被封装在一个库里面,虚拟机和类库的其他部分都可以尽可能以平台无关的方式实现出来。这样一来,将 Java SE 的庞大类库和虚拟机代码移植到其他操作系统的工作就可以被快速的开发出来,从而大大提高了可移植性和程序的可维护性。\r\n\r\n在 Apache 软件基金会资助的开源项目中,有一个类似的平台无关库叫做 Apache Portable Runtime(APR), 这个项目是从 Apache Http Server 等项目的开发过程中提炼和分离出来的,目前已经比较成熟,它与 Harmony 的 Port Layer 的目标有类似之处,但是也有明显的不同,从而使得目前 APR 还不适合作为 Java 虚拟机和类库的平台无关库实现。在本系列后续文章中会有单独的文章详细介绍 Harmony Port Library 的设计特点,并与 APR 进行比较。\r\n\r\nApache Harmony 虚拟机接口\r\n\r\nApache Harmony 虚拟机接口定义了类库和虚拟机之间的接口,Java 规范已经定义了一些虚拟机的 API,比如 Java 本地接口(JNI), Java 虚拟机工具接口(JVMTI)等,但是 Java 规范并没有定义类库和虚拟机之间的接口。Harmony 为了模块化和可移植性的要求,定义了虚拟机接口(VMI),只要是实现了该接口的虚拟机就是 Harmony 兼容虚拟机,从而可以与 Harmony 的类库实现互操作,并且可以与 Harmony 提供的 Java 启动程序协作。\r\n\r\nApache Harmony 虚拟机接口分为三个部分,一部分是 Java 语言接口,由 23 个内核类(Kernel Class)组成,另一部分是 C 语言接口,由 10 个函数组成,最后一部分就是标准 JNI。\r\n\r\n内核类的提出是因为少数核心的公共类是与虚拟机密切相关(VM-specific)的,它们都是属于 java.lang,java.lang.ref,java.lang.reflect 和 java.security 等几个核心的包,比如说 java.lang.ClassLoader, java.lang.ref.WeakReference 等。随着 Java 版本的升级,核心类的数量也可能会增加。Harmony 的类库实现为大多数核心类定义了实现模板。VM 的开发人员可以从零开始实现这些核心类,也可以在 Harmony 提供的模板基础上开始开发。\r\n\r\n虚拟机接口还定义了 VM 必须实现的 10 个 C 函数,用来访问虚拟机和类库共享的数据结构和接口,比如说访问操作系统抽象库(Port Library),虚拟机本地存储空间等。\r\n\r\n虚拟机的最后一部分就是标准 JNI,它在这里的主要用途是允许从 Java 类库的本地链接库中创建 Java 对象。\r\n\r\n应该说虚拟机接口是一个相对宽松的接口,它并不要求对虚拟机和类库特殊的耦合,对垃圾收集,同步和对象的数据结构等等也没有特殊的规定。另外一个著名的开源 Java SE 类库 GNU Classpath 也有类似的虚拟机接口,本系列后续文章将详细介绍 Harmony VMI,并且与 GNU Classpath 比较。\r\n\r\nApache Harmony 启动程序\r\n\r\nApache Harmony 提供了一个启动程序,也就是通常我们用来运行 Java 程序的 java 和 javaw 命令的实现,这个启动程序是个多目标的启动器,可以根据命令行参数启动不同的虚拟机,也可以支持虚拟机特有的选项,如属性文件或命令行参数等。这一切都是基于虚拟机接口,Port Library 和标准 JNI 实现的。\r\n\r\n在进一步介绍启动程序之前,需要先介绍一下 Harmony Development Kit(HDK)和 Harmony JRE 的目录结构,请参考图二。HDK 是一个完整的开发包,不仅仅包括 Harmony 用户所需的所有内容,也提供 Harmony 开发人员所有的静态链接库和头文件,使得他们可以在此基础上对其中任何一部分进行修改和重新构建。\r\n\r\n ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5703, 'java-collections-framework', '重拾Java学习笔记006:Java集合框架', '2012-11-10 02:44:43', '2019-03-25 21:29:22', '

    \"\"

    \r\n

    简化图:

    \r\n

    \"\"

    \r\n

    Java平台提供了一个全新的集合框架。“集合框架”主要由一组用来操作对象的接口组成。不同接口描述一组不同数据类型。

    \r\n

    \"\"

    \r\n

    Java 2集合框架图\r\n集合接口:6个接口(短虚线表示),表示不同集合类型,是集合框架的基础。\r\n抽象类:5个抽象类(长虚线表示),对集合接口的部分实现。可扩展为自定义集合类。\r\n实现类:8个实现类(实线表示),对接口的具体实现。\r\n在很大程度上,一旦您理解了接口,您就理解了框架。虽然您总要创建接口特定的实现,但访问实际集合的方法应该限制在接口方法的使用上;因此,允许您更改基本的数据结构而不必改变其它代码。

    \r\n

    · Collection 接口是一组允许重复的对象。\r\n· Set 接口继承 Collection,但不允许重复,使用自己内部的一个排列机制。\r\n· List 接口继承 Collection,允许重复,以元素安插的次序来放置元素,不会重新排列。\r\n· Map接口是一组成对的键-值对象,即所持有的是key-value pairs。Map中不能有重复的key。拥有自己的内部排列机制。\r\n· 容器中的元素类型都为Object。从容器取得元素时,必须把它转换成原来的类型。

    \r\n

    \"\"

    \r\n

    集合接口

    \r\n

    1.Collection 接口\r\n用于表示任何对象或元素组。想要尽可能以常规方式处理一组元素时,就使用这一接口。

    \r\n

    \"\"

    \r\n

    (1) 单元素添加、删除操作:\r\n        boolean add(Object o):将对象添加给集合\r\nboolean remove(Object o): 如果集合中有与o相匹配的对象,则删除对象o\r\n(2) 查询操作:\r\n        int size() :返回当前集合中元素的数量\r\nboolean isEmpty() :判断集合中是否有任何元素\r\nboolean contains(Object o) :查找集合中是否含有对象o\r\nIterator iterator() :返回一个迭代器,用来访问集合中的各个元素\r\n(3) 组操作 :作用于元素组或整个集合\r\n        boolean containsAll(Collection c): 查找集合中是否含有集合c 中所有元素\r\nboolean addAll(Collection c) : 将集合c 中所有元素添加给该集合\r\nvoid clear(): 删除集合中所有元素\r\nvoid removeAll(Collection c) : 从集合中删除集合c 中的所有元素\r\nvoid retainAll(Collection c) : 从集合中删除集合c 中不包含的元素\r\n(4) Collection转换为Object数组 :\r\n        Object[] toArray() :返回一个内含集合所有元素的array\r\nObject[] toArray(Object[] a) :返回一个内含集合所有元素的array。运行期返回的array和参数a的型别相同,需要转换为正确型别。\r\n此外,您还可以把集合转换成其它任何其它的对象数组。但是,您不能直接把集合转换成基本数据类型的数组,因为集合必须持有对象。\r\n“斜体接口方法是可选的。因为一个接口实现必须实现所有接口方法,调用程序就需要一种途径来知道一个可选的方法是不是不受支持。如果调用一种可选方法 时,一个 UnsupportedOperationException 被抛出,则操作失败,因为方法不受支持。此异常类继承 RuntimeException 类,避免了将所有集合操作放入 try-catch 块。”\r\nCollection不提供get()方法。如果要遍历Collectin中的元素,就必须用Iterator。\r\n1.1.AbstractCollection 抽象类\r\nAbstractCollection 类提供具体“集合框架”类的基本功能。虽然您可以自行实现 Collection 接口的所有方法,但是,除了iterator()和size()方法在恰当的子类中实现以外,其它所有方法都由 AbstractCollection 类来提供实现。如果子类不覆盖某些方法,可选的如add()之类的方法将抛出异常。\r\n1.2.Iterator 接口\r\nCollection 接口的iterator()方法返回一个 Iterator。Iterator接口方法能以迭代方式逐个访问集合中各个元素,并安全的从Collection 中除去适当的元素。

    \r\n

    \"\"

    \r\n

    (1) boolean hasNext(): 判断是否存在另一个可访问的元素\r\nObject next(): 返回要访问的下一个元素。如果到达集合结尾,则抛出NoSuchElementException异常。\r\n(2) void remove(): 删除上次访问返回的对象。本方法必须紧跟在一个元素的访问后执行。如果上次访问后集合已被修改,方法将抛出IllegalStateException。\r\n“Iterator中删除操作对底层Collection也有影响。”\r\n迭代器是 故障快速修复(fail-fast)的。这意味着,当另一个线程修改底层集合的时候,如果您正在用 Iterator 遍历集合,那么,Iterator就会抛出 ConcurrentModificationException (另一种 RuntimeException异常)异常并立刻失败\r\n2.List接口\r\nList 接口继承了 Collection 接口以定义一个允许重复项的有序集合。该接口不但能够对列表的一部分进行处理,还添加了面向位置的操作。

    \r\n

    \"\"

    \r\n

    (1) 面向位置的操作包括插入某个元素或 Collection 的功能,还包括获取、除去或更改元素的功能。在 List 中搜索元素可以从列表的头部或尾部开始,如果找到元素,还将报告元素所在的位置 :\r\nvoid add(int index, Object element): 在指定位置index上添加元素element\r\nboolean addAll(int index, Collection c): 将集合c的所有元素添加到指定位置index\r\nObject get(int index): 返回List中指定位置的元素\r\nint indexOf(Object o): 返回第一个出现元素o的位置,否则返回-1\r\nint lastIndexOf(Object o) :返回最后一个出现元素o的位置,否则返回-1\r\nObject remove(int index) :删除指定位置上的元素\r\nObject set(int index, Object element) :用元素element取代位置index上的元素,并且返回旧的元素\r\n(2) List 接口不但以位置序列迭代的遍历整个列表,还能处理集合的子集:\r\nListIterator listIterator() : 返回一个列表迭代器,用来访问列表中的元素\r\nListIterator listIterator(int index) : 返回一个列表迭代器,用来从指定位置index开始访问列表中的元素\r\nList subList(int fromIndex, int toIndex) :返回从指定位置fromIndex(包含)到toIndex(不包含)范围中各个元素的列表视图\r\n“对子列表的更改(如 add()、remove() 和 set() 调用)对底层 List 也有影响。”\r\n2.1.ListIterator接口\r\nListIterator 接口继承 Iterator 接口以支持添加或更改底层集合中的元素,还支持双向访问。ListIterator没有当前位置,光标位于调用previous和next方法返回的值之间。一个长度为n的列表,有n+1个有效索引值:

    \r\n

                 Element(0)    Element(1)    Element(2)    ...    Element(n)

    \r\n

    Index    1                   2                   3                    ...   n+1

    \r\n

    \"\"

    \r\n

    (1) void add(Object o): 将对象o添加到当前位置的前面\r\nvoid set(Object o): 用对象o替代next或previous方法访问的上一个元素。如果上次调用后列表结构被修改了,那么将抛出IllegalStateException 异常。\r\n(2) boolean hasPrevious(): 判断向后迭代时是否有元素可访问\r\nObject previous():返回上一个对象\r\nint nextIndex(): 返回下次调用next方法时将返回的元素的索引\r\nint previousIndex(): 返回下次调用previous方法时将返回的元素的索引\r\n“正常情况下,不用ListIterator改变某次遍历集合元素的方向 — 向前或者向后。虽然在技术上可以实现,但previous() 后立刻调用next(),返回的是同一个元素。把调用 next()和previous()的顺序颠倒一下,结果相同。”\r\n“我们还需要稍微再解释一下 add() 操作。添加一个元素会导致新元素立刻被添加到隐式光标的前面。因此,添加元素后调用 previous() 会返回新元素,而调用 next() 则不起作用,返回添加操作之前的下一个元素。”\r\n2.2.AbstractList和AbstractSequentialList抽象类\r\n有两个抽象的 List 实现类:AbstractList 和 AbstractSequentialList。像 AbstractSet 类一样,它们覆盖了 equals() 和 hashCode() 方法以确保两个相等的集合返回相同的哈希码。若两个列表大小相等且包含顺序相同的相同元素,则这两个列表相等。这里的 hashCode() 实现在 List 接口定义中指定,而在这里实现。\r\n除了equals()和hashCode(),AbstractList和 AbstractSequentialList实现了其余 List 方法的一部分。因为数据的随机访问和顺序访问是分别实现的,使得具体列表实现的创建更为容易。需要定义的一套方法取决于您希望支持的行为。您永远不必亲自 提供的是 iterator方法的实现。\r\n2.3. LinkedList类和ArrayList类\r\n在“集合框架 ”中有两种常规的 List 实现:ArrayList 和 LinkedList。使用两种 List 实现的哪一种取决于您特定的需要。如果要支持随机访问,而不必在除尾部的任何位置插入或除去元素,那么,ArrayList 提供了可选的集合。但如果,您要频繁的从列表的中间位置添加和除去元素,而只要顺序的访问列表元素,那么,LinkedList 实现更好。\r\n“ArrayList 和 LinkedList 都实现 Cloneable 接口,都提供了两个构造函数,一个无参的,一个接受另一个Collection”\r\n2.3.1. LinkedList类\r\nLinkedList类添加了一些处理列表两端元素的方法。

    \r\n

    \"\"

    \r\n

    (1) void addFirst(Object o): 将对象o添加到列表的开头\r\nvoid addLast(Object o):将对象o添加到列表的结尾\r\n(2) Object getFirst(): 返回列表开头的元素\r\nObject getLast(): 返回列表结尾的元素\r\n(3) Object removeFirst(): 删除并且返回列表开头的元素\r\nObject removeLast():删除并且返回列表结尾的元素\r\n(4) LinkedList(): 构建一个空的链接列表\r\nLinkedList(Collection c): 构建一个链接列表,并且添加集合c的所有元素\r\n“使用这些新方法,您就可以轻松的把 LinkedList 当作一个堆栈、队列或其它面向端点的数据结构。”\r\n2.3.2. ArrayList类\r\nArrayList类封装了一个动态再分配的Object[]数组。每个ArrayList对象有一个capacity。这个capacity表示存储列表中元素的数组的容量。当元素添加到ArrayList时,它的capacity在常量时间内自动增加。\r\n在向一个ArrayList对象添加大量元素的程序中,可使用ensureCapacity方法增加capacity。这可以减少增加重分配的数量。\r\n(1) void ensureCapacity(int minCapacity): 将ArrayList对象容量增加minCapacity\r\n(2) void trimToSize(): 整理ArrayList对象容量为列表当前大小。程序可使用这个操作减少ArrayList对象存储空间。\r\n2.3.2.1. RandomAccess接口\r\n一个特征接口。该接口没有任何方法,不过你可以使用该接口来测试某个集合是否支持有效的随机访问。ArrayList和Vector类用于实现该接口\r\n3.Set接口\r\nSet 接口继承 Collection 接口,而且它不允许集合中存在重复项,每个具体的 Set 实现类依赖添加的对象的 equals()方法来检查独一性。Set接口没有引入新方法,所以Set就是一个Collection,只不过其行为不同。

    \r\n

    \"\"

    \r\n

    3.1. Hash表\r\nHash表是一种数据结构,用来查找对象。Hash表为每个对象计算出一个整数,称为Hash Code(哈希码)。Hash表是个链接式列表的阵列。每个列表称为一个buckets(哈希表元)。对象位置的计算 index = HashCode % buckets (HashCode为对象哈希码,buckets为哈希表元总数)。\r\n当你添加元素时,有时你会遇到已经填充了元素的哈希表元,这种情况称为Hash Collisions(哈希冲突)。这时,你必须判断该元素是否已经存在于该哈希表中。\r\n如果哈希码是合理地随机分布的,并且哈希表元的数量足够大,那么哈希冲突的数量就会减少。同时,你也可以通过设定一个初始的哈希表元数量来更好地控制哈 希表的运行。初始哈希表元的数量为 buckets = size * 150% + 1 (size为预期元素的数量)。\r\n如果哈希 表中的元素放得太满,就必须进行rehashing(再哈希)。再哈希使哈希表元数增倍,并将原有的对象重新导入新的哈希表元中,而原始的哈希表元被删 除。load factor(加载因子)决定何时要对哈希表进行再哈希。在Java编程语言中,加载因子默认值为0.75,默认哈希表元为101。\r\n3.2. Comparable接口和Comparator接口\r\n在“集合框架”中有两种比较接口:Comparable接口和Comparator接口。像String和Integer等Java内建类实现 Comparable接口以提供一定排序方式,但这样只能实现该接口一次。对于那些没有实现Comparable接口的类、或者自定义的类,您可以通过 Comparator接口来定义您自己的比较方式。\r\n3.2.1. Comparable接口\r\n在java.lang包中,Comparable接口适用于一个类有自然顺序的时候。假定对象集合是同一类型,该接口允许您把集合排序成自然顺序。

    \r\n

    \"\"

    \r\n

    (1) int compareTo(Object o): 比较当前实例对象与对象o,如果位于对象o之前,返回负值,如果两个对象在排序中位置相同,则返回0,如果位于对象o后面,则返回正值\r\n在 Java 2 SDK版本1.4中有二十四个类实现Comparable接口。下表展示了8种基本类型的自然排序。虽然一些类共享同一种自然排序,但只有相互可比的类才能排序。

    \r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
    排序
    BigDecimal,BigInteger,Byte, Double, Float,Integer,Long,Short按照数字大小排序
    Character按 Unicode 值的数字大小排序
    String按字符串中字符 Unicode 值排序
    \r\n

    利用Comparable接口创建您自己的类的排序顺序,只是实现compareTo()方法的问题。通常就是依赖几个数据成员的自然排序。同时类也应该覆盖equals()和hashCode()以确保两个相等的对象返回同一个哈希码。\r\n3.2.2. Comparator接口\r\n若一个类不能用于实现java.lang.Comparable,或者您不喜欢缺省的Comparable行为并想提供自己的排序顺序(可能多种排序方式),你可以实现Comparator接口,从而定义一个比较器。

    \r\n

    \"\"

    \r\n

    (1)int compare(Object o1, Object o2): 对两个对象o1和o2进行比较,如果o1位于o2的前面,则返回负值,如果在排序顺序中认为o1和o2是相同的,返回0,如果o1位于o2的后面,则返回正值\r\n“与Comparable相似,0返回值不表示元素相等。一个0返回值只是表示两个对象排在同一位置。由Comparator用户决定如何处理。如果两个不相等的元素比较的结果为零,您首先应该确信那就是您要的结果,然后记录行为。”\r\n(2)boolean equals(Object obj): 指示对象obj是否和比较器相等。\r\n“该方法覆写Object的equals()方法,检查的是Comparator实现的等同性,不是处于比较状态下的对象。”\r\n3.3. SortedSet接口\r\n“集合框架”提供了个特殊的Set接口:SortedSet,它保持元素的有序顺序。SortedSet接口为集的视图(子集)和它的两端(即头和尾) 提供了访问方法。当您处理列表的子集时,更改视图会反映到源集。此外,更改源集也会反映在子集上。发生这种情况的原因在于视图由两端的元素而不是下标元素 指定,所以如果您想要一个特殊的高端元素(toElement)在子集中,您必须找到下一个元素。\r\n添加到SortedSet实现类的元素必须实现Comparable接口,否则您必须给它的构造函数提供一个Comparator接口的实现。 TreeSet类是它的唯一一份实现。\r\n“因为集必须包含唯一的项,如果添加元素时比较两个元素导致了0返回值(通过Comparable的compareTo()方法或Comparator 的compare()方法),那么新元素就没有添加进去。如果两个元素相等,那还好。但如果它们不相等的话,您接下来就应该修改比较方法,让比较方法和 equals() 的效果一致。”

    \r\n

    \"\"

    \r\n

    (1) Comparator comparator(): 返回对元素进行排序时使用的比较器,如果使用Comparable接口的compareTo()方法对元素进行比较,则返回null\r\n(2) Object first(): 返回有序集合中第一个(最低)元素\r\n(3) Object last(): 返回有序集合中最后一个(最高)元素\r\n(4) SortedSet subSet(Object fromElement, Object toElement): 返回从fromElement(包括)至toElement(不包括)范围内元素的SortedSet视图(子集)\r\n(5) SortedSet headSet(Object toElement): 返回SortedSet的一个视图,其内各元素皆小于toElement\r\n(6) SortedSet tailSet(Object fromElement): 返回SortedSet的一个视图,其内各元素皆大于或等于fromElement\r\n3.4. AbstractSet抽象类\r\nAbstractSet类覆盖了Object类的equals()和hashCode()方法,以确保两个相等的集返回相同的哈希码。若两个集大小相等 且包含相同元素,则这两个集相等。按定义,集的哈希码是集中元素哈希码的总和。因此,不论集的内部顺序如何,两个相等的集会有相同的哈希码。\r\n3.4.1. Object类\r\n(1) boolean equals(Object obj): 对两个对象进行比较,以便确定它们是否相同\r\n(2) int hashCode(): 返回该对象的哈希码。相同的对象必须返回相同的哈希码\r\n3.5. HashSet类类和TreeSet类\r\n“集合框架”支持Set接口两种普通的实现:HashSet和TreeSet(TreeSet实现SortedSet接口)。在更多情况下,您会使用 HashSet 存储重复自由的集合。考虑到效率,添加到 HashSet 的对象需要采用恰当分配哈希码的方式来实现hashCode()方法。虽然大多数系统类覆盖了 Object中缺省的hashCode()和equals()实现,但创建您自己的要添加到HashSet的类时,别忘了覆盖 hashCode()和equals()。\r\n当您要从集合中以有序的方式插入和抽取元素时,TreeSet实现会有用处。为了能顺利进行,添加到TreeSet的元素必须是可排序的。\r\n3.5.1.HashSet类\r\n(1) HashSet(): 构建一个空的哈希集\r\n(2) HashSet(Collection c): 构建一个哈希集,并且添加集合c中所有元素\r\n(3) HashSet(int initialCapacity): 构建一个拥有特定容量的空哈希集\r\n(4) HashSet(int initialCapacity, float loadFactor): 构建一个拥有特定容量和加载因子的空哈希集。LoadFactor是0.0至1.0之间的一个数\r\n3.5.2. TreeSet类\r\n(1) TreeSet():构建一个空的树集\r\n(2) TreeSet(Collection c): 构建一个树集,并且添加集合c中所有元素\r\n(3) TreeSet(Comparator c): 构建一个树集,并且使用特定的比较器对其元素进行排序\r\n“comparator比较器没有任何数据,它只是比较方法的存放器。这种对象有时称为函数对象。函数对象通常在“运行过程中”被定义为匿名内部类的一个实例。”\r\nTreeSet(SortedSet s): 构建一个树集,添加有序集合s中所有元素,并且使用与有序集合s相同的比较器排序\r\n3.6. LinkedHashSet类\r\nLinkedHashSet扩展HashSet。如果想跟踪添加给HashSet的元素的顺序,LinkedHashSet实现会有帮助。 LinkedHashSet的迭代器按照元素的插入顺序来访问各个元素。它提供了一个可以快速访问各个元素的有序集合。同时,它也增加了实现的代价,因为 哈希表元中的各个元素是通过双重链接式列表链接在一起的。\r\n(1) LinkedHashSet(): 构建一个空的链接式哈希集\r\n(2) LinkedHashSet(Collection c): 构建一个链接式哈希集,并且添加集合c中所有元素\r\n(3) LinkedHashSet(int initialCapacity): 构建一个拥有特定容量的空链接式哈希集\r\n(4) LinkedHashSet(int initialCapacity, float loadFactor): 构建一个拥有特定容量和加载因子的空链接式哈希集。LoadFactor是0.0至1.0之间的一个数\r\n“为优化HashSet空间的使用,您可以调优初始容量和负载因子。TreeSet不包含调优选项,因为树总是平衡的。”\r\n4. Map接口\r\nMap接口不是Collection接口的继承。Map接口用于维护键/值对(key/value pairs)。该接口描述了从不重复的键到值的映射。

    \r\n

    \"\"

    \r\n

    (1) 添加、删除操作:\r\nObject put(Object key, Object value): 将互相关联的一个关键字与一个值放入该映像。如果该关键字已经存在,那么与此关键字相关的新值将取代旧值。方法返回关键字的旧值,如果关键字原先并不存在,则返回null\r\nObject remove(Object key): 从映像中删除与key相关的映射\r\nvoid putAll(Map t): 将来自特定映像的所有元素添加给该映像\r\nvoid clear(): 从映像中删除所有映射\r\n“键和值都可以为null。但是,您不能把Map作为一个键或值添加给自身。”\r\n(2) 查询操作:\r\nObject get(Object key): 获得与关键字key相关的值,并且返回与关键字key相关的对象,如果没有在该映像中找到该关键字,则返回null\r\nboolean containsKey(Object key): 判断映像中是否存在关键字key\r\nboolean containsValue(Object value): 判断映像中是否存在值value\r\nint size(): 返回当前映像中映射的数量\r\nboolean isEmpty() :判断映像中是否有任何映射\r\n(3) 视图操作 :处理映像中键/值对组\r\nSet keySet(): 返回映像中所有关键字的视图集\r\n“因为映射中键的集合必须是唯一的,您用Set支持。你还可以从视图中删除元素,同时,关键字和它相关的值将从源映像中被删除,但是你不能添加任何元素。”\r\nCollection values():返回映像中所有值的视图集\r\n“因为映射中值的集合不是唯一的,您用Collection支持。你还可以从视图中删除元素,同时,值和它的关键字将从源映像中被删除,但是你不能添加任何元素。”\r\nSet entrySet(): 返回Map.Entry对象的视图集,即映像中的关键字/值对\r\n“因为映射是唯一的,您用Set支持。你还可以从视图中删除元素,同时,这些元素将从源映像中被删除,但是你不能添加任何元素。”\r\n4.1. Map.Entry接口\r\nMap的entrySet()方法返回一个实现Map.Entry接口的对象集合。集合中每个对象都是底层Map中一个特定的键/值对。

    \r\n

    \"\"

    \r\n

    通过这个集合的迭代器,您可以获得每一个条目(唯一获取方式)的键或值并对值进行更改。当条目通过迭代器返回后,除非是迭代器自身的remove()方 法或者迭代器返回的条目的setValue()方法,其余对源Map外部的修改都会导致此条目集变得无效,同时产生条目行为未定义。\r\n(1) Object getKey(): 返回条目的关键字\r\n(2) Object getValue(): 返回条目的值\r\n(3) Object setValue(Object value): 将相关映像中的值改为value,并且返回旧值\r\n4.2. SortedMap接口\r\n“集合框架”提供了个特殊的Map接口:SortedMap,它用来保持键的有序顺序。

    \r\n

    \"\"

    \r\n

    SortedMap接口为映像的视图(子集),包括两个端点提供了访问方法。除了排序是作用于映射的键以外,处理SortedMap和处理 SortedSet一样。\r\n添加到SortedMap实现类的元素必须实现Comparable接口,否则您必须给它的构造函数提供一个Comparator接口的实现。 TreeMap类是它的唯一一份实现。\r\n“因为对于映射来说,每个键只能对应一个值,如果在添加一个键/值对时比较两个键产生了0返回值(通过Comparable的compareTo()方 法或通过Comparator的compare()方法),那么,原始键对应值被新的值替代。如果两个元素相等,那还好。但如果不相等,那么您就应该修改 比较方法,让比较方法和 equals() 的效果一致。”\r\n(1) Comparator comparator(): 返回对关键字进行排序时使用的比较器,如果使用Comparable接口的compareTo()方法对关键字进行比较,则返回null\r\n(2) Object firstKey(): 返回映像中第一个(最低)关键字\r\n(3) Object lastKey(): 返回映像中最后一个(最高)关键字\r\n(4) SortedMap subMap(Object fromKey, Object toKey): 返回从fromKey(包括)至toKey(不包括)范围内元素的SortedMap视图(子集)\r\n(5) SortedMap headMap(Object toKey): 返回SortedMap的一个视图,其内各元素的key皆小于toKey\r\n(6) SortedSet tailMap(Object fromKey): 返回SortedMap的一个视图,其内各元素的key皆大于或等于fromKey\r\n4.3. AbstractMap抽象类\r\n和其它抽象集合实现相似,AbstractMap 类覆盖了equals()和hashCode()方法以确保两个相等映射返回相同的哈希码。如果两个映射大小相等、包含同样的键且每个键在这两个映射中对 应的值都相同,则这两个映射相等。映射的哈希码是映射元素哈希码的总和,其中每个元素是Map.Entry接口的一个实现。因此,不论映射内部顺序如何, 两个相等映射会报告相同的哈希码。\r\n4.4. HashMap类和TreeMap类\r\n“集合框架”提供两种常规的 Map实现:HashMap和TreeMap (TreeMap实现SortedMap接口)。在Map 中插入、删除和定位元素,HashMap 是最好的选择。但如果您要按自然顺序或自定义顺序遍历键,那么TreeMap会更好。使用HashMap要求添加的键类明确定义了hashCode()和 equals()的实现。\r\n这个TreeMap没有调优选项,因为该树总处于平衡状态。\r\n4.4.1. HashMap类\r\n为了优化HashMap空间的使用,您可以调优初始容量和负载因子。\r\n(1) HashMap(): 构建一个空的哈希映像\r\n(2) HashMap(Map m): 构建一个哈希映像,并且添加映像m的所有映射\r\n(3) HashMap(int initialCapacity): 构建一个拥有特定容量的空的哈希映像\r\n(4) HashMap(int initialCapacity, float loadFactor): 构建一个拥有特定容量和加载因子的空的哈希映像\r\n4.4.2. TreeMap类\r\nTreeMap没有调优选项,因为该树总处于平衡状态。\r\n(1) TreeMap():构建一个空的映像树\r\n(2) TreeMap(Map m): 构建一个映像树,并且添加映像m中所有元素\r\n(3) TreeMap(Comparator c): 构建一个映像树,并且使用特定的比较器对关键字进行排序\r\n(4) TreeMap(SortedMap s): 构建一个映像树,添加映像树s中所有映射,并且使用与有序映像s相同的比较器排序\r\n4.5. LinkedHashMap类\r\nLinkedHashMap扩展HashMap,以插入顺序将关键字/值对添加进链接哈希映像中。象LinkedHashSet一样,LinkedHashMap内部也采用双重链接式列表。\r\n(1) LinkedHashMap(): 构建一个空链接哈希映像\r\n(2) LinkedHashMap(Map m): 构建一个链接哈希映像,并且添加映像m中所有映射\r\n(3) LinkedHashMap(int initialCapacity): 构建一个拥有特定容量的空的链接哈希映像\r\n(4) LinkedHashMap(int initialCapacity, float loadFactor): 构建一个拥有特定容量和加载因子的空的链接哈希映像\r\n(5) LinkedHashMap(int initialCapacity, float loadFactor,\r\nboolean accessOrder): 构建一个拥有特定容量、加载因子和访问顺序排序的空的链接哈希映像\r\n“如果将accessOrder设置为true,那么链接哈希映像将使用访问顺序而不是插入顺序来迭\r\n代各个映像。每次调用get或者put方法时,相关的映射便从它的当前位置上删除,然后放到链接式映像列表的结尾处(只有链接式映像列表中的位置才会受到影响,哈希表元则不受影响。哈希表映射总是待在对应于关键字的哈希码的哈希表元中)。”\r\n“该特性对于实现高速缓存的“删除最近最少使用”的原则很有用。例如,你可以希望将最常访问的映射保存在内存中,并且从数据库中读取不经常访问的对象。 当你在表中找不到某个映射,并且该表中的映射已经放得非常满时,你可以让迭代器进入该表,将它枚举的开头几个映射删除掉。这些是最近最少使用的映射。”\r\n(6) protected boolean removeEldestEntry(Map.Entry eldest): 如果你想删除最老的映射,则覆盖该方法,以便返回true。当某个映射已经添加给映像之后,便调用该方法。它的默认实现方法返回false,表示默认条件 下老的映射没有被删除。但是你可以重新定义本方法,以便有选择地在最老的映射符合某个条件,或者映像超过了某个大小时,返回true。\r\n4.6. WeakHashMap类\r\nWeakHashMap是Map的一个特殊实现,它使用WeakReference(弱引用)来存放哈希表关键字。使用这种方式时,当映射的键在 WeakHashMap 的外部不再被引用时,垃圾收集器会将它回收,但它将把到达该对象的弱引用纳入一个队列。WeakHashMap的运行将定期检查该队列,以便找出新到达的 弱应用。当一个弱引用到达该队列时,就表示关键字不再被任何人使用,并且它已经被收集起来。然后WeakHashMap便删除相关的映射。\r\n(1) WeakHashMap(): 构建一个空弱哈希映像\r\n(2) WeakHashMap(Map t): 构建一个弱哈希映像,并且添加映像t中所有映射\r\n(3) WeakHashMap(int initialCapacity): 构建一个拥有特定容量的空的弱哈希映像\r\n(4) WeakHashMap(int initialCapacity, float loadFactor): 构建一个拥有特定容量和加载因子的空的弱哈希映像\r\n4.7. IdentityHashMap类\r\nIdentityHashMap也是Map的一个特殊实现。在这个类中,关键字的哈希码不应该由hashCode()方法来计算,而应该由 System.identityHashCode方法进行计算(即使已经重新定义了hashCode方法)。这是Object.hashCode根据对象 的内存地址来计算哈希码时使用的方法。另外,为了对各个对象进行比较,IdentityHashMap将使用==,而不使用equals方法。\r\n换句话说,不同的关键字对象,即使它们的内容相同,也被视为不同的对象。IdentityHashMap类可以用于实现对象拓扑结构转换 (topology-preserving object graph transformations)(比如实现对象的串行化或深度拷贝),在进行转换时,需要一个“节点表”跟踪那些已经处理过的对象的引用。即使碰巧有对 象相等,“节点表”也不应视其相等。另一个应用是维护代理对象。比如,调试工具希望在程序调试期间维护每个对象的一个代理对象。\r\n“IdentityHashMap类不是一般意义的Map实现!它的实现有意的违背了Map接口要求通过equals方法比较对象的约定。这个类仅使用在很少发生的需要强调等同性语义的情况。”\r\n(1) IdentityHashMap (): 构建一个空的全同哈希映像,默认预期最大尺寸为21\r\n“预期最大尺寸是映像期望把持的键/值映射的最大数目”\r\n(2) IdentityHashMap (Map m): 构建一个全同哈希映像,并且添加映像m中所有映射\r\n(3) IdentityHashMap (int expectedMaxSize): 构建一个拥有预期最大尺寸的空的全同哈希映像。放置超过预期最大尺寸的键/值映射时,将引起内部数据结构的增长,有时可能很费时 。

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5705, 'eclipse-generate-javadoc', 'eclipse生成javadoc', '2012-11-10 06:23:23', '2019-03-25 21:29:22', '
    \r\n
    使用eclipse生成文档(javadoc)主要有三种方法:\r\n1,在项目列表中按右键,选择Export(导出),然后在Export(导出)对话框中选择java下的javadoc,提交到下一步。\r\n在Javadoc Generation对话框中有两个地方要注意的:\r\njavadoc command:应该选择jdk的bin/javadoc.exe\r\ndestination:为生成文档的保存路径,可自由选择。\r\n按finish(完成)提交即可开始生成文档。\r\n2,用菜单选择:File->Export(文件->导出),\r\n剩下的步骤和第一种方法是一样的。\r\n3,选中要生成文档的项目,然后用菜单选择,\r\nProject->Generate Javadoc直接进入Javadoc Generation对话框,剩余的步骤就和第一种方法在Javadoc Generation对话框开始是一样的。\r\n---------------------------------------------------------\r\n\r\n1、选中项目,然后选project->Generate javadoc...,弹出setting对话框。在javadoc command地方选jdkbinjavadoc.exe
    \r\n
    如C:jdk1.6binjavadoc.exe,visibility可以自己设,一般选public,输出路径自己选。
    \r\n
    2、点next,下一步基本不需要设。
    \r\n
    3、再点next,这里要在extra javadoc options地方设定编码,不设的话中文会有乱码。如我的是utf-8,则为
    \r\n
    \r\n
    -encoding UTF-8
    \r\n
    -charset UTF-8
    \r\n
    \r\n
    点finish就可以输出java doc了。
    \r\n \r\n\r\n
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5707, 'java%e8%8e%b7%e5%8f%96class%e5%af%b9%e8%b1%a1%e7%9a%84%e4%b8%89%e7%a7%8d%e6%96%b9%e6%b3%95', '重拾Java学习笔记007:Java获取Class对象的三种方法', '2012-11-12 04:09:35', '2019-03-25 21:29:22', '1 Person.getClass();\r\n2 Class.forName(java.util.Date);\r\n3 Person.class', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5710, 'javs%e7%bb%a7%e6%89%bf%e8%ae%be%e8%ae%a1%e7%9a%84%e6%8a%80%e5%b7%a7', 'Javs继承设计的技巧', '2014-11-15 02:50:26', '2019-03-25 21:29:22', '1 将公共方法的字段定义再超类\r\n2 尽量少用protected\r\n3 不要使用继承实现 is-a的关系\r\n4 除非所有继承的方法都有意义,否则不要使用继承\r\n5 再覆盖方法时,不要改变预期的行为\r\n6 使用多态,而非类型信息\r\n7 不要过多使用反射', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5712, 'java%e5%8f%8d%e5%b0%84%e7%9a%84%e5%9b%9b%e5%a4%a7%e5%8a%9f%e8%83%bd', '重拾Java学习笔记008:Java反射的四大功能', '2012-11-15 02:51:50', '2019-03-25 21:29:22', '1 利用反射分析类的能力\r\n2 在运行中查看对象\r\n4 利用反射动态创建数组\r\n4 利用反射调用任意方法,实现C里面的函数指针和C#里面的委托实现得功能,不建议使用回调,应该用接口和内部类来代替', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5714, 'linq-to-sql-or-linq-to-entities-and-the-sql-query-result-inconsistency-returns-duplicate-results-problem-solving-methods', 'Linq to Sql 或linq to entities 与SQL 查询结果不一致,返回重复结果问题解决方法', '2014-11-15 10:14:23', '2019-03-25 21:29:22', '

    最近用Entity Framework开发项目过程中,发现linq查询返回的结果,与SQL语句查询出的结果不一致。

    \r\n

    问题表现为:SQL返回了我们期望的结果,但是LINQ查询出来的结果确是一些重复记录。

    \r\n

    这种问题一般是对数据库视图进行查询时发生,问题产生的原因及现象如下:

    \r\n

    1)使用.net 的linq to sql,或linq to entities 生成的实体对象,出于为提高效率等原因,会对每个对象自动判断出一些列做为实体对象的Key(EntityKey),

    \r\n

    这个Key就是相当于我们表中的主键,查询结果时,会根据这个Key列的值进行判断,假设数据库中有视图View1有3条记录如下:

    \r\n

    ====View1=====

    \r\n

    列1(key列) 列2 列3

    \r\n

    1             a1    a1

    \r\n

    1             a2    a2

    \r\n

    3             a3    a3

    \r\n

    2)假设此View1的实体对象中,列1判断为Key列(标识列),如果当前我们有一个如下的查询,SQL语句如下:

    \r\n

    SELECT 列1,列2,列3 FROM [View1]

    \r\n

    显然,查询出来正确的结果为:

    \r\n

    ====SQL返回正确的结果=====

    \r\n

    列1(key列) 列2 列3

    \r\n

    1             a1    a1

    \r\n

    1             a2    a2

    \r\n

    3             a3    a3

    \r\n

    3)但是如果你用LINQ语句去查:var objs = objs.entities.select(v=>v);//entities为实体集对象

    \r\n

    得出的结果为:

    \r\n

    ====LINQ返回错误的结果=====

    \r\n

    列1(key列) 列2 列3

    \r\n

    1             a1    a1

    \r\n

    1             a1    a1  (这行是错误的)

    \r\n

    3             a3    a3

    \r\n

    问题分析:

    \r\n

    我们会发现,第2条记录与第一条记录是一样的,原因就在于实体对象中的Key列即列1的值相同(在我们的例子中都为1),

    \r\n

    那么LINQ返回第一条数据时,没有问题,正常返回;

    \r\n

    返回第二条时,判断Key列的值,发现都为1,那么就认为第二条数和第一条数据是一样的,所以直接返回第一行记录的值,做为第二条记录。

    \r\n

    第三条记录,key列不同,取回正确数据。

    \r\n

    解决方法:

    \r\n

    找出视图中可以用来唯一标识该行记录的那些列,将它们设为实体键(Key列)。

    \r\n

    通过上面分析,我们就可以明白为什么出现这种问题都是在使用视图的时候,因为如果是表的话,那么基本上主键会被判断为实体对象的Key,显示不会出现数据重复问题。

    \r\n

    但是视图就不一样,特别是一些GroupBy语句创建的视图,.net底层自动判定的EntityKey,就会有问题,一般都是随便找一个或者几个列,GroupBy 语句的视图中,

    \r\n

    基本上没有哪一个或者哪几个字段能做为记录唯一标识,那么我们只能给记录生成标识列来解决。

    \r\n

    比如有一个视图View2的创建语句如下:

    \r\n

    select col1,col2,col3,count(col4) as col4 from [table] group by col1,col2,col3

    \r\n

    此时为了避免错误的结果,有些朋友,就把视图中col1,col2,col3的列都设为实体键,这样的确可以避免一些问题,有时候列太多了,全设为实体键,不是一个好办法。

    \r\n

    但是,我们可以给记录自动生成列,就是使用 row_number() 方法,比如可以使用如下语句创建视图:

    \r\n

    select  [index]=row_number() over (order by ID), col1,col2,col3,count(col4) as col4 from [table] group by col1,col2,col3

    \r\n

    然后将index列设为实体键就OK了。

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (5716, '%e6%b5%85%e6%8b%b7%e8%b4%9d%e7%a4%ba%e6%84%8f%e5%9b%be', '重拾Java学习笔记009:浅拷贝示意图', '2012-11-16 06:51:05', '2019-03-25 21:29:22', ' \r\n

    深拷贝(深复制)和浅拷贝(浅复制)是两个比较通用的概念,尤其在C++语言中,若不弄懂,则会在delete的时候出问题,但是我们在这幸好用的是Java。虽然java自动管理对象的回收,但对于深拷贝(深复制)和浅拷贝(浅复制),我们还是要给予足够的重视,因为有时这两个概念往往会给我们带来不小的困惑。

    \r\n \r\n

    浅拷贝是指拷贝对象时仅仅拷贝对象本身(包括对象中的基本变量),而不拷贝对象包含的引用指向的对象。深拷贝不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象。举例来说更加清楚:对象A1中包含对B1的引用,B1中包含对C1的引用。浅拷贝A1得到A2,A2 中依然包含对B1的引用,B1中依然包含对C1的引用。深拷贝则是对浅拷贝的递归,深拷贝A1得到A2,A2中包含对B2(B1的copy)的引用,B2 中包含对C2(C1的copy)的引用。

    \r\n \r\n

    若不对clone()方法进行改写,则调用此方法得到的对象即为浅拷贝

    \r\n\"image\"', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6022, '20141125143533', '20141125143533', '2014-11-25 06:35:34', '2019-03-25 21:29:22', '来深圳了,我一定能在深圳立足。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6062, 'the-sql-must-know-it-will-read-the-notes', '《SQL必知必会》阅读笔记', '2014-12-02 09:34:24', '2019-03-25 21:29:22', '2014-12-02\r\n==========\r\n+ **基础**\r\n1 使用SELECT当**没有排序**时,查询出来的数据将以数据在底层表出现的顺序表示。\r\n2 如果不明确规定的排序顺序,则不应该假定检索出来的数据的排序有意义。\r\n\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6085, 'has-some-four-digit-characteristic', '一些四位数具有这样的特点,它的平方根就是它中间两位数字,例如2500平方根为50。编程找出所有这样的四位数。', '2011-12-02 15:31:17', '2019-03-25 21:29:22', '题目\r\n====\r\n一些四位数具有这样的特点,它的平方根就是它中间两位数字,例如2500平方根为50。编程找出所有这样的四位数。\r\nTerwer解答\r\n=========\r\n #include \r\n #include \r\n #include \r\n int main()\r\n {\r\n\r\n int i;\r\n for(i=1000;i<10000;i++){\r\n int left=i%1000;\r\n //int right=i%10;\r\n int middle=left/10;\r\n int temp=middle*middle;\r\n if(i==temp){\r\n printf(\"%dn\",i);\r\n }\r\n }\r\n getchar();\r\n }\r\n\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6091, 'csharp-uses-the-https-system-interface', 'C#使用https开发系统接口以及调用', '2014-12-03 04:40:34', '2019-03-25 21:29:22', '开发:\r\n未完待续\r\n调用篇\r\n=====\r\n1、工具准备\r\n----------\r\nfiddler:http://www.telerik.com/download/fiddler/fiddler4\r\n2、调用准备\r\n-----------\r\nhttpHelper\r\nhttps://github.com/terwer/simulate-login/blob/master/simulate-login/HttpHelper.cs\r\n\r\n\r\nhttp封装2\r\n\r\n using System;\r\n using System.Collections.Generic;\r\n using System.Linq;\r\n using System.Text;\r\n using System.Net;\r\n using System.IO;\r\n\r\n namespace ProductSync\r\n {\r\n /// \r\n /// Http请求封装类\r\n /// \r\n public class HttpHelper\r\n {\r\n /// \r\n /// 发送Post请求\r\n /// \r\n /// url地址\r\n /// 参数\r\n /// 编码格式\r\n /// \r\n public static string Post(string strUrl, string strParm, Encoding encode)\r\n {\r\n byte[] arrB = encode.GetBytes(strParm);\r\n HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(strUrl);\r\n myReq.Method = \"POST\";\r\n myReq.ContentType = \"application/x-www-form-urlencoded\";\r\n myReq.Timeout = 10000;\r\n myReq.ContentLength = (long)((int)arrB.Length);\r\n Stream outStream = myReq.GetRequestStream();\r\n outStream.Write(arrB, 0, (int)arrB.Length);\r\n outStream.Close();\r\n WebResponse myResp = null;\r\n try\r\n {\r\n myResp = myReq.GetResponse();\r\n }\r\n catch (Exception exception)\r\n {\r\n throw exception;\r\n }\r\n StreamReader readStream = new StreamReader(myResp.GetResponseStream(), encode);\r\n char[] read = new char[256];\r\n int count = readStream.Read(read, 0, 256);\r\n string str = null;\r\n while (count > 0)\r\n {\r\n str = string.Concat(str, new string(read, 0, count));\r\n count = readStream.Read(read, 0, 256);\r\n }\r\n readStream.Close();\r\n myResp.Close();\r\n return str;\r\n }\r\n }\r\n\r\n\r\n\r\n }\r\n\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6096, 'osgi-net-learning', 'OSGI .NET学习', '2014-12-04 13:53:05', '2019-03-25 21:29:22', 'Introduction\r\n===========\r\nWelcome to OSGi.NET, here we’are sharing anything about OSGi for .NET or OSGi.NET, whatever you call it.\r\n\r\nOSGi.NET, a dynamic modularization framework, which is a .NET implementation tightly based on OSGi specifications from OSGi Alliance, is designed and developed by Xi’an UI Information Technology, Inc., in China, from 2008.\r\nhttps://osgi.codeplex.com/', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6099, 'study-on-message-queuing-msmq-and-call-c-implementation', '初探消息队列MSMQ及C#的调用实现', '2014-12-05 07:22:01', '2019-03-26 00:12:33', '
    概述\r\n ====\r\n MSMQ全称MicroSoft Message Queue,微软消息队列,是在多个不同的应用之间实现相互通信的一种异步传输模式,相互通信的应用可以分布于同一台机器上,也可以分布于相连的网络空间中的任一位置。它的实现原理是:消息的发送者把自己想要发送的信息放入一个容器中(我们称之为Message),然后把它保存至一个系统公用空间的消息队列(Message Queue)中;本地或者是异地的消息接收程序再从该队列中取出发给它的消息进行处理。\r\n\r\n消息Message是由通信的双方所需要传递的信息。\r\n\r\n类型\r\n ====\r\n 队列的类型主要包括一下几种:\r\n\r\n“公共队列”在整个“消息队列”网络中复制,并且有可能由网络连接的所有站点访问。\r\n\r\n“专用队列”不在整个网络中发布。相反,它们仅在所驻留的本地计算机上可用。专用队列只能由知道队列的完整路径名或标签的应用程序访问。\r\n\r\n“管理队列”包含确认在给定“消息队列”网络中发送的消息回执的消息。指定希望 MessageQueue 组件使用的管理队列(如果有的话)。\r\n\r\n“响应队列”包含目标应用程序接收到消息时返回给发送应用程序的响应消息。指定希望 MessageQueue 组件使用的响应队列(如果有的话)。\r\n\r\n优点:稳定、消息优先级、脱机能力以及安全性,有保障的消息传递和执行许多业务处理的可靠的防故障机制。\r\n\r\n缺点:MSMQ不适合于Client需要Server端实时交互情况.大量请求时候,响应延迟.\r\n 使用(Win7打开消息队列)\r\n =======================\r\n [![QQ截图20141205152755](http://bcs.duapp.com/terwer/blog/2014/12/QQ截图20141205152755.png)](http://bcs.duapp.com/terwer/blog/2014/12/QQ截图20141205152755.png)\r\n 参考\r\n ===\r\n\r\nhttp://www.cnblogs.com/tenghoo/archive/2009/11/05/1596456.html\r\n\r\nhttp://www.cnblogs.com/xinhaijulan/archive/2010/08/22/1805768.html\r\n\r\nhttp://www.cnblogs.com/CopyPaster/archive/2011/01/21/1941339.html
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6108, 'c-console-program-receives-multiple-parameter-handling', 'C#控制台程序接收多个参数的处理', '2014-12-05 10:57:36', '2019-03-25 21:29:22', 'using System;\r\nusing System.Collections.Generic;\r\nusing System.Data;\r\nusing System.IO;\r\nusing System.Linq;\r\nusing System.Text;\r\nusing System.Web;\r\nusing Newtonsoft.Json;\r\nusing ProductBLL;\r\n\r\nnamespace ProductSync\r\n{\r\n internal class Program\r\n {\r\n private static void Main(string[] args)\r\n {\r\n if (args.Length < 1)\r\n {\r\n Console.WriteLine(\"请输入参数进行相应的同步操作:n -i 同步商品到宝安电商平台(-i+id同步单个,例如-i11799)n -s 更新库存(-s+id同步单个,例如-s11799)n -m 更新上下架(-m+id同步单个,例如-m11799)n -p 更新价格(-s+id同步单个,例如-p11799)\");\r\n }\r\n else\r\n {\r\n foreach (string key in args)\r\n {\r\n //同步商品到宝安电商平台\r\n if (key.StartsWith(\"-i\"))\r\n {\r\n string value = key.Replace(\"-i\", \"\");\r\n //默认同步所有的商品\r\n if (String.IsNullOrEmpty(value))\r\n {\r\n dynamic rmsg = ProductApi.SyncAllGoodsInfo();\r\n Console.Write(rmsg);\r\n }\r\n //输入id同步单个商品\r\n else\r\n {\r\n int productId = 0;\r\n if (!Utils.IsNumber(value))\r\n {\r\n Console.Write(\"id输入非法!\");\r\n return;\r\n }\r\n else\r\n {\r\n productId = int.Parse(value);\r\n }\r\n dynamic rmsg = ProductApi.SyncSingleGoodsInfo(productId);\r\n Console.Write(rmsg);\r\n }\r\n }\r\n else if (key.StartsWith(\"-s\"))\r\n {\r\n string value = key.Replace(\"-s\", \"\");\r\n //默认更新所有的商品库存\r\n if (String.IsNullOrEmpty(value))\r\n {\r\n dynamic rmsg = ProductApi.SyncAllGoodsStore();\r\n Console.Write(rmsg);\r\n }\r\n else\r\n {\r\n int productId = 0;\r\n if (!Utils.IsNumber(value))\r\n {\r\n Console.Write(\"id输入非法!\");\r\n return;\r\n }\r\n else\r\n {\r\n productId = int.Parse(value);\r\n }\r\n dynamic rmsg = ProductApi.SyncSingleGoodsStore(productId);\r\n Console.Write(rmsg);\r\n }\r\n }\r\n else if (key.StartsWith(\"-m\"))\r\n {\r\n string value = key.Replace(\"-m\", \"\");\r\n //默认更新所有的商品上下架\r\n if (String.IsNullOrEmpty(value))\r\n {\r\n dynamic rmsg = ProductApi.SyncAllGoodsMarketable();\r\n Console.Write(rmsg);\r\n }\r\n else\r\n {\r\n int productId = 0;\r\n if (!Utils.IsNumber(value))\r\n {\r\n Console.Write(\"id输入非法!\");\r\n return;\r\n }\r\n else\r\n {\r\n productId = int.Parse(value);\r\n }\r\n dynamic rmsg = ProductApi.SyncSingleGoodsMarketable(productId);\r\n Console.Write(rmsg);\r\n }\r\n }\r\n else if (key.StartsWith(\"-p\"))\r\n {\r\n string value = key.Replace(\"-p\", \"\");\r\n //默认更新所有的商品价格\r\n if (String.IsNullOrEmpty(value))\r\n {\r\n dynamic rmsg = ProductApi.SyncAllGoodsPrice();\r\n Console.Write(rmsg);\r\n }\r\n else\r\n {\r\n int productId = 0;\r\n if (!Utils.IsNumber(value))\r\n {\r\n Console.Write(\"id输入非法!\");\r\n return;\r\n }\r\n else\r\n {\r\n productId = int.Parse(value);\r\n }\r\n dynamic rmsg = ProductApi.SyncSingleGoodsPrice(productId);\r\n Console.Write(rmsg);\r\n }\r\n }\r\n else\r\n {\r\n// Dictionary CatMap = new Dictionary();\r\n// CatMap.Add(1, 1);\r\n// CatMap.Add(2, 2);\r\n//\r\n// string config = JsonConvert.SerializeObject(CatMap);\r\n// string appPath = System.AppDomain.CurrentDomain.BaseDirectory + \"\\config\";\r\n// if (!Directory.Exists(appPath))\r\n// {\r\n// Directory.CreateDirectory(appPath);\r\n// }\r\n// string filePath = appPath + \"\\catmap.txt\";\r\n// StreamWriter fs = new StreamWriter(filePath, false, System.Text.Encoding.Default);\r\n// fs.Write(config);\r\n// fs.Close();\r\n// return;\r\n Console.WriteLine(\"参数错误!\");\r\n }\r\n }\r\n }\r\n }\r\n }\r\n}', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6113, 'wordpressw-version-upgrade-tips-box-to-remove-or-hide-the-background-remove-the-upgrade-prompt', 'WordPressw去除或隐藏后台版本升级提示框,去掉升级提示', '2014-12-10 02:28:29', '2019-03-25 21:29:22', '1 在functions.php或自定义插件里面加上如下代码\r\n //隐藏升级提示\r\n function wp_hide_nag() {\r\n remove_action( \'admin_notices\', \'update_nag\', 3);\r\n }\r\n add_action(\'admin_menu\',\'wp_hide_nag\');\r\n2 打开wp-admin/wp-includes.update.php查找\r\n echo \"
    $msg
    \";\r\n并将其删除就可以了。\r\n这下,整个世界清净了。。。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6116, 'recent-wordpress-gravatar-avatars-to-be-shielded-lead-site-slow-issues', '解决近期WordPress Gravatar头像被屏蔽导致网站速度变慢问题', '2014-12-11 01:07:25', '2019-03-25 21:29:22', '问题描述\r\n=======\r\n\r\n最近群里又有很多小伙伴私下咨询小V,为什么最近wordpress又开始变的很慢了,不管是前台还是后台,而且谷歌字体已经替换成360的镜像服务上了。但还是奇慢无比,今天小V抽空查看了下,原来是著名的Gravatar头像又被伟大的墙给屏蔽了。\r\n\r\n解决方案\r\n=======\r\n\r\n调用ssl 头像链接\r\nhttps还是没被墙的,而且速度还不错,直接调用这个最简单了。\r\n如果你的网站启用了ssl则不需要了,否则functions.php 加入如下代码\r\nfunction get_ssl_avatar($avatar) {\r\n $avatar = preg_replace(\'/.*/avatar/(.*)?s=([d]+)&.*/\',\'\',$avatar);\r\n return $avatar;\r\n}\r\nadd_filter(\'get_avatar\', \'get_ssl_avatar\');', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6118, 'talk-about-removing-method-of-character-at-the-end-of', '说说去除末尾字符的方法', '2014-12-11 01:32:06', '2019-03-25 21:29:22', 'String str;\r\n1 str=str.TrimEnd(\',\');\r\n\r\nStringBuilder\r\n1 在for循环里面控制\r\nsb.Append(j == drSecond.Length - 1 ? \"}\" : \"},\");', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6127, 'correct-method-of-obtaining-a-cookie', '正确获取Cookie的方法', '2014-12-12 03:08:43', '2019-03-25 21:29:22', '错误的方法\r\n========\r\nztdNo = Utils.ReqStrParams(\"rbZtd\", \"\");//获取不到\r\n\r\n正确的方法\r\n=========\r\nRequest.Cookies[\"Cookie_ZtdNo\"] == null ? \"\" : Request.Cookies[\"Cookie_ZtdNo\"].Value.ToString();', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6129, 'set-nocount-on-sql-on', '关于SQL中的SET NOCOUNT ON', '2014-12-12 09:28:43', '2019-03-25 21:29:22', '作用\r\n====\r\n阻止在结果集中返回可显示受 Transact-SQL 语句或存储过程影响的行计数的消息。\r\n语法\r\n====\r\n SET NOCOUNT { ON | OFF }\r\n分析\r\n===\r\n当 SET NOCOUNT 为 ON 时,不返回计数。当 SET NOCOUNT 为 OFF 时,返回计数。\r\n即使当 SET NOCOUNT 为 ON 时,也更新 @@ROWCOUNT 函数。\r\n当 SET NOCOUNT 为 ON 时,将不向客户端发送存储过程中每个语句的 DONE_IN_PROC 消息。如果存储过程中包含一些并不返回许多实际数据的语句,网络通信流量便会大量减少,因此,将 SET NOCOUNT 设置为 ON 可显著提高性能。\r\nSET NOCOUNT 指定的设置是在执行或运行时生效,而不是在分析时生效。\r\n权限\r\n===\r\n要求具有 public 角色的成员身份。\r\n示例\r\n====\r\n USE AdventureWorks;\r\n GO\r\n SET NOCOUNT OFF;\r\n GO\r\n -- Display the count message.\r\n SELECT TOP(5)LastName\r\n FROM Person.Contact\r\n WHERE LastName LIKE \'A%\';\r\n GO\r\n -- SET NOCOUNT to ON to no longer display the count message.\r\n SET NOCOUNT ON;\r\n GO\r\n SELECT TOP(5) LastName\r\n FROM Person.Contact\r\n WHERE LastName LIKE \'A%\';\r\n GO\r\n -- Reset SET NOCOUNT to OFF\r\n SET NOCOUNT OFF;\r\n GO', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6131, '20141213140344', '20141213140344', '2014-12-13 06:03:46', '2019-03-25 21:29:22', '.net立足,重拾java,探索c++,深入Android。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6136, '20141216195040', '20141216195040', '2014-12-16 11:50:42', '2019-03-25 21:29:22', '开始整理自己。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6137, '20141216195201', '20141216195201', '2014-12-16 11:52:02', '2019-03-25 21:29:22', '任何时候都不能敷衍。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6142, 'blogs-hosted-on-github-and-sync-with-wordpress-in-real-time', '将博客托管到Github,并与Wordpress保持实时同步', '2014-12-18 05:34:46', '2019-03-25 21:29:22', '环境准备\r\n=======\r\n申请域名\r\n在Github创建版本仓库\r\n配置域名别名解析\r\n配置Github\r\nhttp://beiyuu.com/github-pages/\r\nCentos安装git\r\n[root@AY140529210959Z home]# :yum install git -y\r\n克隆版本库\r\n[root@AY140529210959Z terwer]# git clone https://github.com/terwer/terwer.github.io\r\n\r\n[root@AY140529210959Z terwer]# cd terwer.github.io\r\n\r\n用jekyllrb跟新博客\r\nhttp://jekyllrb.com/\r\n\r\nhttp://rubyinstaller.org/downloads/\r\n\r\nRuby http://dl.bintray.com/oneclick/rubyinstaller/rubyinstaller-2.1.5.exe?direct\r\n\r\nDevkit http://cdn.rubyinstaller.org/archives/devkits/DevKit-mingw64-64-4.7.2-20130224-1432-sfx.exe\r\n\r\n安装jekyll\r\ngem install jekyll\r\n\r\njekyll serve\r\n注意事项\r\n\r\n=======\r\n\r\n1 安装devkit之后一定要执行postinstall里面的\r\n\r\n2 Ruby和Devkit版本一定要对应\r\n3 切换到devkit目录,执行\r\nruby dk.rb init\r\nruby dk.rb install\r\n未完待续\"QQ截图20141218224116\"', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6150, 'centos-configure-rabbitmq-message-queue', 'CentOS配置RabbitMQ消息队列', '2014-12-18 06:00:39', '2019-03-25 21:29:22', 'http://www.rabbitmq.com/install-generic-unix.html\r\n未完待续', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6155, 'notepad-markdown-plug-in-is-installed', 'notepad 安装markdown插件', '2014-12-19 01:17:46', '2019-03-25 21:29:22', '
    前言\r\n====\r\nNotepad++ 是一款非常友好的编辑器,轻巧、便捷、高效、插件丰富… 同时 Notepad++ 支持用户自定义语法高亮\r\n\r\nNotepad让Markdown高亮的方法\r\n===========================\r\n我修改过的Markdown规则 https://github.com/terwer/markdown_npp_zenburn\r\n让Notepad++ 高亮支持 Markdown 语法的方法:\r\n1、开始菜单 -> 运行(或者直接按 Ctrl+R) -> 输入 ```%APPDATA%\\Notepad++```,将```userDefineLang.xml```放置到此目录。\r\n2、重启 Notepad++。\r\n3、在语言菜单下可以看到自定义的 Markdown 高亮规则。\r\n\r\n源码下载\r\n========\r\n附上我个人的Markdown高亮代码文件(针对黑色背景)\r\n因Github里的高亮支持文件表现不是非常理想,所以我加以修改并分享出来。\r\n[点击下载我的Markdown高亮代码文件](https://raw.githubusercontent.com/terwer/markdown_npp/master/terwer_theme/userDefineLang.xml)
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6158, 'commonly-used-linux-commands', 'Linux常用命令', '2014-12-19 01:28:56', '2019-03-25 21:29:22', '
    列表\r\n====\r\n列表 ```ls [-l]```\r\n\r\n文件相关\r\n=========\r\n查看、当前目录 ```pwd```\r\n转换目录 ```pwd```\r\n设置权限 ```chmod 777 /var/home/terwer```\r\n删除(目录必须有-rf) ```rm -rf terwer```\r\n解压 ```unzip```\r\n\r\nmv移动命令\r\n==========\r\nmv 命令是move的缩写。 用它从一个目录到一个目录移动/重命名文件。   mv命令不同于cp命令,mv命令是完全的从源移动文件并且把文件移动到指定的目录,这里cp命令只是复制文件的内容从一个文件到另一个文件。\r\n语法:\r\n语法是\r\nmv [-f] [-i] 原名称 新名称\r\n命令开关:\r\n-f 在覆盖前不提示(equivalent to相当于 –reply=yes). mv -f     将在没有提示的情况下移动文件(多个文件),即使它将复写存在的目标文件。\r\n-i 在复写另一文件前做出提示\r\nmv /root/terwer/* /home/terwer\r\n编辑文件 vim test.sh\r\nesc 退出编辑模式\r\n:q退出 :q!强制退出\r\n:w写入 :w@!强制写入\r\n查看所有已经安装的库 yum list installed      
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6167, 'hand-write-http-simulation-tool-001-interface-and-technical-options', '自己动手写Http模拟工具001:界面及技术选择', '2014-12-19 02:14:38', '2019-03-25 21:29:22', '未完待续', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6169, 'js-url-encoded-parameters-urlencode', 'JS中URL编码参数(UrlEncode)', '2014-12-19 08:45:19', '2019-03-25 21:29:22', '网上有很多文字作品写涉及在JS中呈现类似UrlEncode功能时都是自定义参数来呈现,其实JS中本身就有那样的参数。\r\n参数parameter由于用类似URL的形式传过去 , 所以别直接就那样赋值\r\n以下是对变量值的URL编码总结 : 意见用encodeURIComponent() , GET 和POST方法都能够发送过去\r\nJava编程script中存在几种对URL字符串停止编码的窍门:escape(),encodeURI(),以及encodeURIComponent()。这几种编码所起的功能各不相同。\r\nescape() 窍门:\r\n采用ISO Latin字符集对指定的字符串停止编码。所有的空格符、标点符号、特殊字符以及更多有联系非ASCII字符都将被转化成%xx各式的字符编码(xx等于该字符在字符集表里面的编码的16进制数字)。比如,空格符对应的编码是%20。\r\n不会被此窍门编码的字符: @ * / +\r\nencodeURI() 窍门:\r\n把URI字符串采用UTF-8编码各式转化成escape各式的字符串。\r\n不会被此窍门编码的字符:! @ # $& * ( ) = : / ; ? + \'\r\nencodeURIComponent() 窍门:\r\n把URI字符串采用UTF-8编码各式转化成escape各式的字符串。与encodeURI()相比,那个窍门将对更多的字符停止编码,比如 / 等字符。所以假如字符串里面包含了URI的几个部份的话,别用那个窍门来停止编码,否则 / 字符被编码之后URL将呈现错误。\r\n不会被此窍门编码的字符:! * ( ) \'\r\n\r\n因此,对于汉文字符串来说,假如不期望把字符串编码各式转化成UTF-8各式的(比如原页面和目的页面的charset是一致的时候),只需求应用 escape。假如你的页面是GB2312或者更多有联系的编码,而接受参数parameter的页面是UTF-8编码的,就要采用encodeURI或者encodeURIComponent。\r\n\r\n参考\r\nhttp://www.cnblogs.com/neru/archive/2010/07/10/1774718.html', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6173, 'wpf-learning-notes-002-sender-discussion', 'WPF学习笔记002:从sender说开去', '2014-12-20 15:03:57', '2019-03-25 21:29:22', '未完待续', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6185, 'errors-on-dll-failed-to-add-reference-a-reference-to-xxx-could-not-be-added', '关于dll添加引用失败的错误:A reference to 'XXX' could not be added', '2014-12-21 06:22:08', '2019-03-25 21:29:22', '

    错误信息

    \r\n\"QQ截图20141221141729\"\r\n\r\nA reference to \'D:MyCodeEnrollWebEnrollDllCCBRSA.dll\' could not be added. Please make sure that the file is accessible, and that it is a valid assembly or COM component.\r\n

    原因分析

    \r\n这是因为要添加引用的dll没有注册\r\n

    解决方案

    \r\n使用regsvr32 xxx.dll注册之后再重新添加引用即可。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6193, 'win7-registered-dll-error-module-cbrsa-dll-are-loaded-but-the-call-to-dllregisterserver-failed', 'win7注册dll错误:模块"CBRSA.dll"已加载,但对 DllRegisterServer 的调用失败', '2014-12-21 06:38:52', '2019-03-25 21:29:22', '

    错误信息

    \r\n\"QQ截图20141221143522\"\r\n\r\n模块“CCBRSA.dll”已加载,但对 DllRegisterServer 的调用失败,错误代码为 0x8000ffff。\r\n

    原因分析及解决方案

    \r\n这是因为权限不够,应该以管理员身份运行cmd(方法:点击开始,搜索 cmd ,然后右键 \"以管理员身份运行\"即可),就可以了。\r\n\r\n\"QQ截图20141221144341\"', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6216, 'winform-note-001-entry-function', 'Winform学习笔记001:入口函数', '2014-12-21 07:40:48', '2019-03-25 21:29:22', '新建Winform时会默认有一个Program.cs文件,里面Mian函数如下:\r\n
    \r\n
    \r\n
      \r\n
    1. using System;
    2. \r\n
    3. using System.Collections.Generic;
    4. \r\n
    5. using System.Linq;
    6. \r\n
    7. using System.Windows.Forms;
    8. \r\n
    9. \r\n
    10. namespace OneBlog.Winform
    11. \r\n
    12. {
    13. \r\n
    14.     static class Program
    15. \r\n
    16.     {
    17. \r\n
    18.         /// <summary>
    19. \r\n
    20.         /// The main entry point for the application.
    21. \r\n
    22.         /// </summary>
    23. \r\n
    24.         [STAThread]
    25. \r\n
    26.         static void Main()
    27. \r\n
    28.         {
    29. \r\n
    30.             Application.EnableVisualStyles();
    31. \r\n
    32.             Application.SetCompatibleTextRenderingDefault(false);
    33. \r\n
    34.             Application.Run(new frmLogin());
    35. \r\n
    36.         }
    37. \r\n
    38.     }
    39. \r\n
    40. }
    41. \r\n
    \r\n
    \r\n其中 Application.Run()里面创建不同的Form类,就可以默认启动相应的窗口。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6226, 'winform-study-notes-002-hide-window-border', 'Winform学习笔记002:隐藏窗口边框和标题栏', '2014-12-21 09:03:46', '2019-03-25 21:29:22', '方法1、设置当前窗口的FormBorderStyle属性值为None 或者 在构造函数中添加 Form.FormBorderStyle = false;\r\n\r\n方法2、在构造函数中添加 Form.ControlBox = false;(此法只是去掉控制按钮)\r\n效果如下:\r\n\"2014-12-21_171029\"', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6227, 'winform-study-notes-003-inserting-resources', 'Winform学习笔记003:插入资源', '2014-12-21 09:04:43', '2019-03-25 21:29:22', '直接点击属性框里面的Image后面的浏览图标,出来以下界面:\r\n\r\n\"2014-12-21_182412\"\r\n\r\n然后点击Import选择图片路径,导入图片即可。最终效果:\r\n\r\n\"2014-12-21_182722\"', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6240, '20141221172205', '20141221172205', '2014-12-21 09:22:05', '2019-03-25 21:29:22', '很高兴,以前那个爱探索,追求极致的terwer又回来了。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6248, 'winform-study-notes-004-windows-minimize', 'Winform学习笔记004:窗口最小化', '2014-12-21 13:46:16', '2019-03-25 21:29:22', 'this.WindowState = FormWindowState.Minimized;\r\n\r\n或者\r\n\r\n1.设置WinForm窗体属性showinTask=false\r\n\r\n2.加notifyicon控件notifyIcon1,为控件notifyIcon1的属性Icon添加一个icon图标。\r\n\r\n3.添加窗体最小化事件(首先需要添加事件引用):\r\n\r\nthis.SizeChanged += new System.EventHandler(this.Form1_SizeChanged);\r\n\r\n//上面一行是主窗体InitializeComponent()方法中需要添加的引用\r\n\r\nprivate void Form1_SizeChanged(object sender, EventArgs e)\r\n{\r\nif(this.WindowState == FormWindowState.Minimized)\r\n{\r\nthis.Hide();\r\nthis.notifyIcon1.Visible=true;\r\n}\r\n}\r\n\r\n4.添加点击图标事件(首先需要添加事件引用):\r\n\r\nprivate void notifyIcon1_Click(object sender, EventArgs e)\r\n{\r\nthis.Visible = true;\r\nthis.WindowState = FormWindowState.Normal;\r\nthis.notifyIcon1.Visible = false;\r\n}\r\n5.可以给notifyIcon添加右键菜单:\r\n\r\n主窗体中拖入一个ContextMenu控件NicontextMenu,点中控件,在上下文菜单中添加菜单,notifyIcon1的ContextMenu行为中选中NicontextMenu 作为上下文菜单。\r\n\r\nthis.notifyIcon1 = new System.Windows.Forms.NotifyIcon(this.components);\r\nthis.NicontextMenu = new System.Windows.Forms.ContextMenu();\r\nthis.menuItem_Hide = new System.Windows.Forms.MenuItem();\r\nthis.menuItem_Show = new System.Windows.Forms.MenuItem();\r\nthis.menuItem_Aubot = new System.Windows.Forms.MenuItem();\r\nthis.menuItem_Exit = new System.Windows.Forms.MenuItem();\r\nthis.notifyIcon1.ContextMenu = this.NicontextMenu;\r\nthis.notifyIcon1.Icon = ((System.Drawing.Icon)(resources.GetObject( \"NotifyIcon.Icon \")));\r\nthis.notifyIcon1.Text = \" \";\r\nthis.notifyIcon1.Visible = true;\r\nthis.notifyIcon1.DoubleClick += new System.EventHandler(this.notifyIcon1_DoubleClick);\r\nthis.notifyIcon1.Click += new System.EventHandler(this.notifyIcon1_Click);\r\nthis.NicontextMenu.MenuItems.AddRange(\r\n\r\nnew System.Windows.Forms.MenuItem[]\r\n{\r\nthis.menuItem_Hide,\r\nthis.menuItem_Show,\r\nthis.menuItem_Aubot,\r\nthis.menuItem_Exit\r\n}\r\n);\r\n\r\n//\r\n//       menuItem_Hide\r\n//\r\nthis.menuItem_Hide.Index = 0;\r\nthis.menuItem_Hide.Text = \"隐藏 \";\r\nthis.menuItem_Hide.Click += new System.EventHandler(this.menuItem_Hide_Click);\r\n//\r\n//       menuItem_Show\r\n//\r\nthis.menuItem_Show.Index = 1;\r\nthis.menuItem_Show.Text = \"显示 \";\r\nthis.menuItem_Show.Click += new System.EventHandler(this.menuItem_Show_Click);\r\n//\r\n//       menuItem_Aubot\r\n//\r\nthis.menuItem_Aubot.Index = 2;\r\nthis.menuItem_Aubot.Text = \"关于 \";\r\nthis.menuItem_Aubot.Click += new System.EventHandler(this.menuItem_Aubot_Click);\r\n//\r\n//       menuItem_Exit\r\n//\r\nthis.menuItem_Exit.Index = 3;\r\nthis.menuItem_Exit.Text = \"退出 \";\r\nthis.menuItem_Exit.Click += new System.EventHandler(this.menuItem_Exit_Click);\r\n\r\nprotected  override  void  OnClosing(CancelEventArgs e)\r\n{\r\nthis.ShowInTaskbar = false;\r\nthis.WindowState = FormWindowState.Minimized;\r\ne.Cancel = true;\r\n}\r\nprotected  override  void  OnClosing(CancelEventArgs e)\r\n{\r\n//this.ShowInTaskbar = false;\r\nthis.WindowState = FormWindowState.Minimized;\r\ne.Cancel = true;\r\n}\r\n\r\nprivate  void  CloseCtiServer()\r\n{\r\ntimer.Enabled = false;\r\nDJ160API.DisableCard();\r\nthis.NotifyIcon.Visible = false;\r\nthis.Close();\r\nthis.Dispose();\r\nApplication.Exit();\r\n}\r\n\r\nprivate  void  HideCtiServer()\r\n{\r\nthis.Hide();\r\n}\r\n\r\nprivate  void  ShowCtiServer()\r\n{\r\nthis.Show();\r\nthis.WindowState = FormWindowState.Normal;\r\nthis.Activate();\r\n\r\n}\r\nprivate  void  CtiManiForm_Closing(object sender, System.ComponentModel.CancelEventArgs e)\r\n{\r\nthis.CloseCtiServer();\r\n}\r\n\r\nprivate  void  menuItem_Show_Click(object sender, System.EventArgs e)\r\n{\r\nthis.ShowCtiServer();\r\n}\r\n\r\nprivate  void  menuItem_Aubot_Click(object sender, System.EventArgs e)\r\n{\r\n\r\n}\r\n\r\nprivate  void  menuItem_Exit_Click(object sender, System.EventArgs e)\r\n{\r\nthis.CloseCtiServer();\r\n}\r\n\r\nprivate  void  menuItem_Hide_Click(object sender, System.EventArgs e)\r\n{\r\nthis.HideCtiServer();\r\n}\r\n\r\nprivate  void  CtiManiForm_SizeChanged(object sender, System.EventArgs e)\r\n{\r\nif(this.WindowState == FormWindowState.Minimized)\r\n{\r\nthis.HideCtiServer();\r\n}\r\n}\r\n

    private  void  notifyIcon1_DoubleClick(object sender,System.EventArgs e)\r\n{\r\nthis.ShowCtiServer();\r\n}

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6251, 'winform-study-notes-open-page-in-005winform', 'Winform学习笔记005:Winform中打开网页', '2014-12-21 13:59:10', '2019-03-25 21:29:22', '1、首先比较简单的我们知道有类似的方法如下    \r\n\r\nSystem.Diagnostics.Process.Start(\"http://www.baidu.com\");\r\n\r\n
    2、比较灵活一点,可以定义窗口大小,我们要实现网页中脚本打开页面的方法,即window.open。那么,我们必然会想,如何调用页面的脚本呢?其实可以利用WebBrowser来实现\r\n
    \r\n
    \r\n
      \r\n
    1. //连接
    2. \r\n
    3. string url =\"http://www.baidu.com\";
    4. \r\n
    5. //定义脚本
    6. \r\n
    7. string script =@\"<script language=\'javascript\' type=\'text/javascript\'>
    8. \r\n
    9. function openUrl(url){
    10. \r\n
    11. window.open(url,\'测试窗口\',\'width=400px,height=400px,directories=true,location=false,menubar=false,resizeable=false,scrollbars=yes,toolbar=false \');
    12. \r\n
    13. }</script>\";
    14. \r\n
    15. WebBrowser wb =new WebBrowser();
    16. \r\n
    17. wb.DocumentText=@\"<html> <head>\"+ script +\"</head><body></body></html>\";//定义WebBrowser中的DOM文档
    18. \r\n
    19. wb.DocumentCompleted+=delegate
    20. \r\n
    21. {
    22. \r\n
    23. //执行脚本函数
    24. \r\n
    25. wb.Document.InvokeScript(\"openUrl\",newobject[]{ url });
    26. \r\n
    27. };
    28. \r\n
    \r\n
    \r\n ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6253, 'winform-study-notes-006-menu-move-the-mouse-to-move-the-effects', 'Winform学习笔记006:菜单鼠标移入移出效果', '2014-12-21 14:38:24', '2019-03-25 21:29:22', '

    代码实现

    \r\n
    \r\n
    \r\n
      \r\n
    1. /// <summary>
    2. \r\n
    3. /// 鼠标移上去的效果
    4. \r\n
    5. /// </summary>
    6. \r\n
    7. /// <param name=\"sender\"></param>
    8. \r\n
    9. /// <param name=\"e\"></param>
    10. \r\n
    11. private void topPan_MouseEnter(object sender, EventArgs e)
    12. \r\n
    13. {
    14. \r\n
    15. Label lb = (Label)sender;
    16. \r\n
    17. lb.BorderStyle = BorderStyle.Fixed3D;
    18. \r\n
    19. }
    20. \r\n
    21. /// <summary>
    22. \r\n
    23. /// 鼠标离开的效果
    24. \r\n
    25. /// </summary>
    26. \r\n
    27. /// <param name=\"sender\"></param>
    28. \r\n
    29. /// <param name=\"e\"></param>
    30. \r\n
    31. private void topPan_MouseLeave(object sender, EventArgs e)
    32. \r\n
    33. {
    34. \r\n
    35. Label lb = (Label)sender;
    36. \r\n
    37. lb.BorderStyle = BorderStyle.None;
    38. \r\n
    39. }
    40. \r\n
    \r\n
    \r\n

    演示

    \r\n\"2014-12-21_223546\"\r\n\r\n ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6259, 'winform-note-007-menu-click-the-toggle-event', 'Winform学习笔记007:菜单点击切换事件', '2014-12-21 15:31:17', '2019-03-25 21:29:22', '

    效果

    \r\n\"2014-12-21_233043\"\r\n

    代码

    \r\n
    \r\n
    \r\n
      \r\n
    1. using System;
    2. \r\n
    3. using System.Collections.Generic;
    4. \r\n
    5. using System.ComponentModel;
    6. \r\n
    7. using System.Data;
    8. \r\n
    9. using System.Drawing;
    10. \r\n
    11. using System.Linq;
    12. \r\n
    13. using System.Text;
    14. \r\n
    15. using System.Windows.Forms;
    16. \r\n
    17. \r\n
    18. namespace OneBlog.Winform
    19. \r\n
    20. {
    21. \r\n
    22.     public partial class frmMain : Form
    23. \r\n
    24.     {
    25. \r\n
    26.         public frmMain()
    27. \r\n
    28.         {
    29. \r\n
    30.             InitializeComponent();
    31. \r\n
    32.         }
    33. \r\n
    34. \r\n
    35.         private void frmMain_Load(object sender, EventArgs e)
    36. \r\n
    37.         {
    38. \r\n
    39.             //触发 点击 Wordpress 按钮 事件
    40. \r\n
    41.             topPan_Menu_Click(panWP, null);
    42. \r\n
    43.         }
    44. \r\n
    45. \r\n
    46.         private void lbClose_Click(object sender, EventArgs e)
    47. \r\n
    48.         {
    49. \r\n
    50.             Application.Exit();
    51. \r\n
    52.         }
    53. \r\n
    54. \r\n
    55.         private void lbSmall_Click(object sender, EventArgs e)
    56. \r\n
    57.         {
    58. \r\n
    59.             this.WindowState = FormWindowState.Minimized;
    60. \r\n
    61.         }
    62. \r\n
    63. \r\n
    64.         private void lblogo_Click(object sender, EventArgs e)
    65. \r\n
    66.         {
    67. \r\n
    68.             System.Diagnostics.Process.Start(\"http://www.terwer.com\");
    69. \r\n
    70.         }
    71. \r\n
    72. \r\n
    73.         /// <summary>
    74. \r\n
    75.         /// 鼠标移上去的效果
    76. \r\n
    77.         /// </summary>
    78. \r\n
    79.         /// <param name=\"sender\"></param>
    80. \r\n
    81.         /// <param name=\"e\"></param>
    82. \r\n
    83.         private void topPan_MouseEnter(object sender, EventArgs e)
    84. \r\n
    85.         {
    86. \r\n
    87.             Label lb = (Label) sender;
    88. \r\n
    89.             lb.BorderStyle = BorderStyle.Fixed3D;
    90. \r\n
    91.         }
    92. \r\n
    93. \r\n
    94.         /// <summary>
    95. \r\n
    96.         /// 鼠标离开的效果
    97. \r\n
    98.         /// </summary>
    99. \r\n
    100.         /// <param name=\"sender\"></param>
    101. \r\n
    102.         /// <param name=\"e\"></param>
    103. \r\n
    104.         private void topPan_MouseLeave(object sender, EventArgs e)
    105. \r\n
    106.         {
    107. \r\n
    108.             Label lb = (Label) sender;
    109. \r\n
    110.             lb.BorderStyle = BorderStyle.None;
    111. \r\n
    112.         }
    113. \r\n
    114. \r\n
    115.         /// <summary>
    116. \r\n
    117.         /// 菜单点击切换时间
    118. \r\n
    119.         /// </summary>
    120. \r\n
    121.         /// <param name=\"sender\"></param>
    122. \r\n
    123.         /// <param name=\"e\"></param>
    124. \r\n
    125.         private void topPan_Menu_Click(object sender, EventArgs e)
    126. \r\n
    127.         {
    128. \r\n
    129.             Label lb = (Label) sender;
    130. \r\n
    131. \r\n
    132.             bool isExist = false;
    133. \r\n
    134. \r\n
    135.             //显示最新的该显示的页面,页面置顶
    136. \r\n
    137.             foreach (Control ctr in panMain.Controls)
    138. \r\n
    139.             {
    140. \r\n
    141.                 if (ctr.Text == lb.Name)
    142. \r\n
    143.                 {
    144. \r\n
    145.                     //避免重复添加
    146. \r\n
    147.                     isExist = true;
    148. \r\n
    149.                     //窗口移到最前
    150. \r\n
    151.                     ctr.BringToFront();
    152. \r\n
    153.                 }
    154. \r\n
    155.             }
    156. \r\n
    157. \r\n
    158. \r\n
    159.             if (!isExist)
    160. \r\n
    161.             {
    162. \r\n
    163.                 Form longPage;
    164. \r\n
    165.                 //点击切换触发事件(相应窗体)
    166. \r\n
    167.                 if (lb.Name == \"panWP\")
    168. \r\n
    169.                 {
    170. \r\n
    171.                     MessageBox.Show(\"panWP\");
    172. \r\n
    173.                     longPage = new panWP();
    174. \r\n
    175.                 }
    176. \r\n
    177.                 else if (lb.Name == \"panCnblogs\")
    178. \r\n
    179.                 {
    180. \r\n
    181.                     MessageBox.Show(\"panCnblogs\");
    182. \r\n
    183.                     longPage = new panCnblogs();
    184. \r\n
    185.                 }
    186. \r\n
    187.                 else if (lb.Name == \"panSET\")
    188. \r\n
    189.                 {
    190. \r\n
    191.                     MessageBox.Show(\"panSET\");
    192. \r\n
    193.                     longPage = new panSET();
    194. \r\n
    195.                 }
    196. \r\n
    197.                 else
    198. \r\n
    199.                 {
    200. \r\n
    201.                     MessageBox.Show(\"panWP default\");
    202. \r\n
    203.                     longPage = new panWP();
    204. \r\n
    205.                 }
    206. \r\n
    207. \r\n
    208.                 longPage.TopLevel = false;
    209. \r\n
    210.                 //添加窗口到panl
    211. \r\n
    212.                 this.panMain.Controls.Add(longPage);
    213. \r\n
    214.                 longPage.Show();
    215. \r\n
    216.                 //窗口移到最前
    217. \r\n
    218.                 longPage.BringToFront();
    219. \r\n
    220.             }
    221. \r\n
    222.         }
    223. \r\n
    224.     }
    225. \r\n
    226. }
    227. \r\n
    \r\n
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6264, 'learn-sql-sever-note-020-write-diaries-and-empty-the-log', 'SQL Sever学习笔记020:写日志与清空日志', '2014-12-22 01:53:50', '2019-03-25 21:29:22', '
    \r\n
    \r\n
      \r\n
    1. --写日志测试开始
    2. \r\n
    3. --测试写入
    4. \r\n
    5. --exec logger \'test\'
    6. \r\n
    7. --清空表数据
    8. \r\n
    9. --TRUNCATE  TABLE [log]
    10. \r\n
    11. select * from log order by addtime desc;
    12. \r\n
    13. --写日志测试结束
    14. \r\n
    \r\n
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6268, '4-class-join-query-sql-server-learning-notes-inner-joinleft-join-right-join-full-outer-join', 'SQL Server学习笔记021:4类join查询:inner join,left join, right join, full outer join', '2014-12-22 04:34:05', '2019-03-25 21:29:22', '
    \r\n\r\n1.from A inner join B on A.ID=B.ID :两表都有的记录才列出\r\n\r\nA表:  ID   Name                           B表: ID  Class\r\n\r\n1      BMW                                   1     C1\r\n\r\n2      Aodi                                    2     C2\r\n\r\nNull    Benz                                  4     Null\r\n\r\n3        Null                                   Null   C4\r\n\r\n \r\n\r\nselect  * from A inner join B on A.ID=B.ID:\r\n\r\nID       Name            ID        Class\r\n\r\n1        BMW              1         C1\r\n\r\n2         Aodi              2         C2\r\n\r\n2.from A left join B on A.ID=B.ID:\r\n\r\nA表中所有记录列出,B中无法匹配的用Null匹配\r\n\r\nA表:  ID   Name                           B表: ID  Class\r\n\r\n1      BMW                                   1     C1\r\n\r\n2      Aodi                                    2     C2\r\n\r\nNull    Benz                                  4     Null\r\n\r\n3        Null                                   Null   C4\r\n\r\nselect  * from A left join B on A.ID=B.ID:\r\n\r\nID       Name            ID        Class\r\n\r\n1        BMW             1          C1\r\n\r\n2        Aodi              2          C2\r\n\r\nNull      Benz             Null       Null\r\n\r\n3        Null               Null        Null\r\n\r\n \r\n\r\n3.from A right join B on A.ID=B.ID:\r\n\r\nB表中所有记录列出,A中无法匹配的用Null匹配\r\n\r\nA表:  ID   Name                           B表: ID  Class\r\n\r\n1      BMW                                   1     C1\r\n\r\n2      Aodi                                    2     C2\r\n\r\nNull    Benz                                  4     Null\r\n\r\n3        Null                                   Null   C4\r\n\r\nselect  * from A right join B on A.ID=B.ID:\r\n\r\nID       Name                   ID        Class\r\n\r\n1          BMW                     1           C1\r\n\r\n2         Aodi                       2           C2\r\n\r\nNull      Null                        4           Null\r\n\r\nNull      Null                       Null        C4\r\n\r\n4.from A full outer join B on A.ID=B.ID.\r\n\r\n列出A表所有记录,B表所有记录。无法匹配的用Null替代\r\n\r\nA表:  ID   Name                           B表: ID  Class\r\n\r\n1      BMW                                   1     C1\r\n\r\n2      Aodi                                    2     C2\r\n\r\nNull    Benz                                  4     Null\r\n\r\n3        Null                                   Null   C4\r\n\r\nselect * from A full outer join B on A.ID=B.ID.\r\n\r\nID       Name                   ID        Class\r\n\r\n1      BMW                     1         C1\r\n\r\n2      Aodi                      2        C2\r\n\r\nNull   Benz                     Null     Null\r\n\r\n3       Null                       Null    Null\r\n\r\nNull     Null                       4        Null\r\n\r\nNull    Null                        Null      C4\r\n\r\n \r\n\r\n其它join查询:\r\n\r\n(1) left outer join,等价于left join.\r\n\r\n(2)right outer join, 等价于right join.\r\n\r\n(3) cross join,    笛卡尔乘积查询\r\n\r\n参考\r\n\r\nhttp://www.cnblogs.com/albert1017/archive/2012/07/27/2611898.html\r\n\r\n
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6275, 'sql-server-learning-note-022-associated-bulk-updates', 'SQL Server学习笔记022:多表关联批量更新', '2014-12-22 08:52:21', '2019-03-25 21:29:22', '
    \r\n
    \r\n
      \r\n
    1. --更新goodslockstorage表中的锁库存数量
    2. \r\n
    3. --购物车商品临时表
    4. \r\n
    5. SELECT  g.goodsid,g.productid,g.cinvcode,g.sizeid,ct.Quantity
    6. \r\n
    7. INTO #groupcart2
    8. \r\n
    9. FROM goods g(nolock) ,#groupcart ct(nolock)
    10. \r\n
    11. where
    12. \r\n
    13. g.goodsid=ct.goodsid
    14. \r\n
    15. \r\n
    16. update s set s.LockStorage=s.LockStorage+ct.quantity
    17. \r\n
    18. from #groupcart2 ct(nolock)
    19. \r\n
    20. LEFT JOIN psn.dbo.cusstock c ON c.cinvcode=ct.cinvcode and c.sizeid=ct.sizeid AND c.ccuscode=@ztdno
    21. \r\n
    22. LEFT JOIN goodslockstorage s ON s.GoodsID=ct.goodsid AND s.ztdno=@ztdno
    23. \r\n
    24. where
    25. \r\n
    26. s.goodsid=ct.GoodsID
    27. \r\n
    28. and ((c.inum-s.LockStorage)-ct.Quantity)>=0
    29. \r\n
    \r\n
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6278, 'sql-server-learning-notes-023-bulk-insert', 'SQL Server学习笔记023:批量插入', '2014-12-22 09:17:12', '2019-03-25 21:29:22', '
    \r\n
    \r\n
      \r\n
    1. --添加goodslockstorage表添加新的记录
    2. \r\n
    3. --goodslockstorage表中不存在,则添加
    4. \r\n
    5. INSERT INTO goodslockstorage  select ct.goodsid,@ztdNo AS ztdno,,ct.Quantity as lockstorage from #groupcart2  ct
    6. \r\n
    7. WHERE  NOT EXISTS (SELECT g.goodsid  FROM goodslockstorage g WHERE g.goodsid=ct.goodsid)
    8. \r\n
    \r\n
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6281, 'c-learning-notes-005byte-data-types', 'c#学习笔记005:Byte数据类型', '2012-12-22 16:05:56', '2019-03-25 21:29:22', '

    MSDN

    \r\nhttp://msdn.microsoft.com/zh-cn/library/system.byte(v=vs.110).aspx\r\n

    源码

    \r\n
    \r\n
    \r\n
      \r\n
    1. using System.Globalization;
    2. \r\n
    3. using System.Runtime.InteropServices;
    4. \r\n
    5. using System.Security;
    6. \r\n
    7. \r\n
    8. namespace System
    9. \r\n
    10. {
    11. \r\n
    12.     /// <summary>Represents an 8-bit unsigned integer.</summary>
    13. \r\n
    14.     /// <filterpriority>1</filterpriority>
    15. \r\n
    16.     [__DynamicallyInvokable]
    17. \r\n
    18.     [ComVisible(true)]
    19. \r\n
    20.     [Serializable]
    21. \r\n
    22.     public struct Byte : IComparable, IFormattable, IConvertible, IComparable<byte>, IEquatable<byte>
    23. \r\n
    24.     {
    25. \r\n
    26.         /// <summary>Represents the largest possible value of a <see cref=\"T:System.Byte\" />. This field is constant.</summary>
    27. \r\n
    28.         /// <filterpriority>1</filterpriority>
    29. \r\n
    30.         [__DynamicallyInvokable]
    31. \r\n
    32.         public const byte MaxValue = 255;
    33. \r\n
    34. \r\n
    35.         /// <summary>Represents the smallest possible value of a <see cref=\"T:System.Byte\" />. This field is constant.</summary>
    36. \r\n
    37.         /// <filterpriority>1</filterpriority>
    38. \r\n
    39.         [__DynamicallyInvokable]
    40. \r\n
    41.         public const byte MinValue = 0;
    42. \r\n
    43. \r\n
    44.         private byte m_value;
    45. \r\n
    46. \r\n
    47.         /// <summary>Compares this instance to a specified object and returns an indication of their relative values.</summary>
    48. \r\n
    49.         /// <returns>A signed integer that indicates the relative order of this instance and <paramref name=\"value\" />.Return Value Description Less than zero This instance is less than <paramref name=\"value\" />. Zero This instance is equal to <paramref name=\"value\" />. Greater than zero This instance is greater than <paramref name=\"value\" />.-or- <paramref name=\"value\" /> is null. </returns>
    50. \r\n
    51.         /// <param name=\"value\">An object to compare, or null. </param>
    52. \r\n
    53.         /// <exception cref=\"T:System.ArgumentException\">
    54. \r\n
    55.         ///   <paramref name=\"value\" /> is not a <see cref=\"T:System.Byte\" />. </exception>
    56. \r\n
    57.         /// <filterpriority>2</filterpriority>
    58. \r\n
    59.         public int CompareTo(object value)
    60. \r\n
    61.         {
    62. \r\n
    63.             if (value == null)
    64. \r\n
    65.             {
    66. \r\n
    67.                 return 1;
    68. \r\n
    69.             }
    70. \r\n
    71.             if (!(value is byte))
    72. \r\n
    73.             {
    74. \r\n
    75.                 throw new ArgumentException(Environment.GetResourceString(\"Arg_MustBeByte\"));
    76. \r\n
    77.             }
    78. \r\n
    79.             return this - (byte)value;
    80. \r\n
    81.         }
    82. \r\n
    83. \r\n
    84.         /// <summary>Compares this instance to a specified 8-bit unsigned integer and returns an indication of their relative values.</summary>
    85. \r\n
    86.         /// <returns>A signed integer that indicates the relative order of this instance and <paramref name=\"value\" />.Return Value Description Less than zero This instance is less than <paramref name=\"value\" />. Zero This instance is equal to <paramref name=\"value\" />. Greater than zero This instance is greater than <paramref name=\"value\" />. </returns>
    87. \r\n
    88.         /// <param name=\"value\">An 8-bit unsigned integer to compare. </param>
    89. \r\n
    90.         /// <filterpriority>2</filterpriority>
    91. \r\n
    92.         [__DynamicallyInvokable]
    93. \r\n
    94.         public int CompareTo(byte value)
    95. \r\n
    96.         {
    97. \r\n
    98.             return this - value;
    99. \r\n
    100.         }
    101. \r\n
    102. \r\n
    103.         /// <summary>Returns a value indicating whether this instance is equal to a specified object.</summary>
    104. \r\n
    105.         /// <returns>true if <paramref name=\"obj\" /> is an instance of <see cref=\"T:System.Byte\" /> and equals the value of this instance; otherwise, false.</returns>
    106. \r\n
    107.         /// <param name=\"obj\">An object to compare with this instance, or null. </param>
    108. \r\n
    109.         /// <filterpriority>2</filterpriority>
    110. \r\n
    111.         [__DynamicallyInvokable]
    112. \r\n
    113.         public override bool Equals(object obj)
    114. \r\n
    115.         {
    116. \r\n
    117.             if (!(obj is byte))
    118. \r\n
    119.             {
    120. \r\n
    121.                 return false;
    122. \r\n
    123.             }
    124. \r\n
    125.             return this == (byte)obj;
    126. \r\n
    127.         }
    128. \r\n
    129. \r\n
    130.         /// <summary>Returns a value indicating whether this instance and a specified <see cref=\"T:System.Byte\" /> object represent the same value.</summary>
    131. \r\n
    132.         /// <returns>true if <paramref name=\"obj\" /> is equal to this instance; otherwise, false.</returns>
    133. \r\n
    134.         /// <param name=\"obj\">A <see cref=\"T:System.Byte\" /> object to compare to this instance.</param>
    135. \r\n
    136.         /// <filterpriority>2</filterpriority>
    137. \r\n
    138.         [__DynamicallyInvokable]
    139. \r\n
    140.         public bool Equals(byte obj)
    141. \r\n
    142.         {
    143. \r\n
    144.             return this == obj;
    145. \r\n
    146.         }
    147. \r\n
    148. \r\n
    149.         /// <summary>Returns the hash code for this instance.</summary>
    150. \r\n
    151.         /// <returns>A hash code for the current <see cref=\"T:System.Byte\" />.</returns>
    152. \r\n
    153.         /// <filterpriority>2</filterpriority>
    154. \r\n
    155.         [__DynamicallyInvokable]
    156. \r\n
    157.         public override int GetHashCode()
    158. \r\n
    159.         {
    160. \r\n
    161.             return this;
    162. \r\n
    163.         }
    164. \r\n
    165. \r\n
    166.         /// <summary>Returns the <see cref=\"T:System.TypeCode\" /> for value type <see cref=\"T:System.Byte\" />.</summary>
    167. \r\n
    168.         /// <returns>The enumerated constant, <see cref=\"F:System.TypeCode.Byte\" />.</returns>
    169. \r\n
    170.         /// <filterpriority>2</filterpriority>
    171. \r\n
    172.         public TypeCode GetTypeCode()
    173. \r\n
    174.         {
    175. \r\n
    176.             return TypeCode.Byte;
    177. \r\n
    178.         }
    179. \r\n
    180. \r\n
    181.         /// <summary>Converts the string representation of a number to its <see cref=\"T:System.Byte\" /> equivalent.</summary>
    182. \r\n
    183.         /// <returns>The <see cref=\"T:System.Byte\" /> value equivalent to the number contained in <paramref name=\"s\" />.</returns>
    184. \r\n
    185.         /// <param name=\"s\">A string containing a number to convert. The string is interpreted using the <see cref=\"F:System.Globalization.NumberStyles.Integer\" /> style. </param>
    186. \r\n
    187.         /// <exception cref=\"T:System.ArgumentNullException\">
    188. \r\n
    189.         ///   <paramref name=\"s\" /> is null. </exception>
    190. \r\n
    191.         /// <exception cref=\"T:System.FormatException\">
    192. \r\n
    193.         ///   <paramref name=\"s\" /> is not of the correct format. </exception>
    194. \r\n
    195.         /// <exception cref=\"T:System.OverflowException\">
    196. \r\n
    197.         ///   <paramref name=\"s\" /> represents a number less than <see cref=\"F:System.Byte.MinValue\" /> or greater than <see cref=\"F:System.Byte.MaxValue\" />. </exception>
    198. \r\n
    199.         /// <filterpriority>1</filterpriority>
    200. \r\n
    201.         [__DynamicallyInvokable]
    202. \r\n
    203.         public static byte Parse(string s)
    204. \r\n
    205.         {
    206. \r\n
    207.             return byte.Parse(s, NumberStyles.Integer, NumberFormatInfo.CurrentInfo);
    208. \r\n
    209.         }
    210. \r\n
    211. \r\n
    212.         /// <summary>Converts the string representation of a number in a specified style to its <see cref=\"T:System.Byte\" /> equivalent.</summary>
    213. \r\n
    214.         /// <returns>The <see cref=\"T:System.Byte\" /> value equivalent to the number contained in <paramref name=\"s\" />.</returns>
    215. \r\n
    216.         /// <param name=\"s\">A string containing a number to convert. The string is interpreted using the style specified by <paramref name=\"style\" />. </param>
    217. \r\n
    218.         /// <param name=\"style\">A bitwise combination of <see cref=\"T:System.Globalization.NumberStyles\" /> values that indicates the style elements that can be present in <paramref name=\"s\" />. A typical value to specify is <see cref=\"F:System.Globalization.NumberStyles.Integer\" />.</param>
    219. \r\n
    220.         /// <exception cref=\"T:System.ArgumentNullException\">
    221. \r\n
    222.         ///   <paramref name=\"s\" /> is null. </exception>
    223. \r\n
    224.         /// <exception cref=\"T:System.FormatException\">
    225. \r\n
    226.         ///   <paramref name=\"s\" /> is not of the correct format. </exception>
    227. \r\n
    228.         /// <exception cref=\"T:System.OverflowException\">
    229. \r\n
    230.         ///   <paramref name=\"s\" /> represents a number less than <see cref=\"F:System.Byte.MinValue\" /> or greater than <see cref=\"F:System.Byte.MaxValue\" />. -or-<paramref name=\"s\" /> includes non-zero, fractional digits.</exception>
    231. \r\n
    232.         /// <exception cref=\"T:System.ArgumentException\">
    233. \r\n
    234.         ///   <paramref name=\"style\" /> is not a <see cref=\"T:System.Globalization.NumberStyles\" /> value. -or-<paramref name=\"style\" /> is not a combination of <see cref=\"F:System.Globalization.NumberStyles.AllowHexSpecifier\" /> and <see cref=\"F:System.Globalization.NumberStyles.HexNumber\" /> values.</exception>
    235. \r\n
    236.         /// <filterpriority>1</filterpriority>
    237. \r\n
    238.         [__DynamicallyInvokable]
    239. \r\n
    240.         public static byte Parse(string s, NumberStyles style)
    241. \r\n
    242.         {
    243. \r\n
    244.             NumberFormatInfo.ValidateParseStyleInteger(style);
    245. \r\n
    246.             return byte.Parse(s, style, NumberFormatInfo.CurrentInfo);
    247. \r\n
    248.         }
    249. \r\n
    250. \r\n
    251.         /// <summary>Converts the string representation of a number in a specified culture-specific format to its <see cref=\"T:System.Byte\" /> equivalent.</summary>
    252. \r\n
    253.         /// <returns>The <see cref=\"T:System.Byte\" /> value equivalent to the number contained in <paramref name=\"s\" />.</returns>
    254. \r\n
    255.         /// <param name=\"s\">A string containing a number to convert. The string is interpreted using the <see cref=\"F:System.Globalization.NumberStyles.Integer\" /> style. </param>
    256. \r\n
    257.         /// <param name=\"provider\">An <see cref=\"T:System.IFormatProvider\" /> that supplies culture-specific parsing information about <paramref name=\"s\" />. If <paramref name=\"provider\" /> is null, the thread current culture is used. </param>
    258. \r\n
    259.         /// <exception cref=\"T:System.ArgumentNullException\">
    260. \r\n
    261.         ///   <paramref name=\"s\" /> is null. </exception>
    262. \r\n
    263.         /// <exception cref=\"T:System.FormatException\">
    264. \r\n
    265.         ///   <paramref name=\"s\" /> is not of the correct format. </exception>
    266. \r\n
    267.         /// <exception cref=\"T:System.OverflowException\">
    268. \r\n
    269.         ///   <paramref name=\"s\" /> represents a number less than <see cref=\"F:System.Byte.MinValue\" /> or greater than <see cref=\"F:System.Byte.MaxValue\" />. </exception>
    270. \r\n
    271.         /// <filterpriority>1</filterpriority>
    272. \r\n
    273.         [__DynamicallyInvokable]
    274. \r\n
    275.         public static byte Parse(string s, IFormatProvider provider)
    276. \r\n
    277.         {
    278. \r\n
    279.             return byte.Parse(s, NumberStyles.Integer, NumberFormatInfo.GetInstance(provider));
    280. \r\n
    281.         }
    282. \r\n
    283. \r\n
    284.         /// <summary>Converts the string representation of a number in a specified style and culture-specific format to its <see cref=\"T:System.Byte\" /> equivalent.</summary>
    285. \r\n
    286.         /// <returns>The <see cref=\"T:System.Byte\" /> value equivalent to the number contained in <paramref name=\"s\" />.</returns>
    287. \r\n
    288.         /// <param name=\"s\">A string containing a number to convert. The string is interpreted using the style specified by <paramref name=\"style\" />. </param>
    289. \r\n
    290.         /// <param name=\"style\">A bitwise combination of <see cref=\"T:System.Globalization.NumberStyles\" /> values that indicates the style elements that can be present in <paramref name=\"s\" />. A typical value to specify is <see cref=\"F:System.Globalization.NumberStyles.Integer\" />.</param>
    291. \r\n
    292.         /// <param name=\"provider\">An <see cref=\"T:System.IFormatProvider\" /> object that supplies culture-specific information about the format of <paramref name=\"s\" />. If <paramref name=\"provider\" /> is null, the thread current culture is used. </param>
    293. \r\n
    294.         /// <exception cref=\"T:System.ArgumentNullException\">
    295. \r\n
    296.         ///   <paramref name=\"s\" /> is null. </exception>
    297. \r\n
    298.         /// <exception cref=\"T:System.FormatException\">
    299. \r\n
    300.         ///   <paramref name=\"s\" /> is not of the correct format. </exception>
    301. \r\n
    302.         /// <exception cref=\"T:System.OverflowException\">
    303. \r\n
    304.         ///   <paramref name=\"s\" /> represents a number less than <see cref=\"F:System.Byte.MinValue\" /> or greater than <see cref=\"F:System.Byte.MaxValue\" />. -or-<paramref name=\"s\" /> includes non-zero, fractional digits.</exception>
    305. \r\n
    306.         /// <exception cref=\"T:System.ArgumentException\">
    307. \r\n
    308.         ///   <paramref name=\"style\" /> is not a <see cref=\"T:System.Globalization.NumberStyles\" /> value. -or-<paramref name=\"style\" /> is not a combination of <see cref=\"F:System.Globalization.NumberStyles.AllowHexSpecifier\" /> and <see cref=\"F:System.Globalization.NumberStyles.HexNumber\" /> values.</exception>
    309. \r\n
    310.         /// <filterpriority>1</filterpriority>
    311. \r\n
    312.         [__DynamicallyInvokable]
    313. \r\n
    314.         public static byte Parse(string s, NumberStyles style, IFormatProvider provider)
    315. \r\n
    316.         {
    317. \r\n
    318.             NumberFormatInfo.ValidateParseStyleInteger(style);
    319. \r\n
    320.             return byte.Parse(s, style, NumberFormatInfo.GetInstance(provider));
    321. \r\n
    322.         }
    323. \r\n
    324. \r\n
    325.         private static byte Parse(string s, NumberStyles style, NumberFormatInfo info)
    326. \r\n
    327.         {
    328. \r\n
    329.             int num = 0;
    330. \r\n
    331.             try
    332. \r\n
    333.             {
    334. \r\n
    335.                 num = Number.ParseInt32(s, style, info);
    336. \r\n
    337.             }
    338. \r\n
    339.             catch (OverflowException overflowException)
    340. \r\n
    341.             {
    342. \r\n
    343.                 throw new OverflowException(Environment.GetResourceString(\"Overflow_Byte\"), overflowException);
    344. \r\n
    345.             }
    346. \r\n
    347.             if (num < 0 || num > 255)
    348. \r\n
    349.             {
    350. \r\n
    351.                 throw new OverflowException(Environment.GetResourceString(\"Overflow_Byte\"));
    352. \r\n
    353.             }
    354. \r\n
    355.             return (byte)num;
    356. \r\n
    357.         }
    358. \r\n
    359. \r\n
    360.         /// <summary>For a description of this member, see <see cref=\"M:System.IConvertible.ToBoolean(System.IFormatProvider)\" />. </summary>
    361. \r\n
    362.         /// <returns>true if the value of the current instance is not zero; otherwise, false.</returns>
    363. \r\n
    364.         /// <param name=\"provider\">This parameter is ignored.</param>
    365. \r\n
    366.         bool System.IConvertible.ToBoolean(IFormatProvider provider)
    367. \r\n
    368.         {
    369. \r\n
    370.             return Convert.ToBoolean(this);
    371. \r\n
    372.         }
    373. \r\n
    374. \r\n
    375.         /// <summary>For a description of this member, see <see cref=\"M:System.IConvertible.ToByte(System.IFormatProvider)\" />. </summary>
    376. \r\n
    377.         /// <returns>The value of the current instance, unchanged.</returns>
    378. \r\n
    379.         /// <param name=\"provider\">This parameter is ignored.</param>
    380. \r\n
    381.         byte System.IConvertible.ToByte(IFormatProvider provider)
    382. \r\n
    383.         {
    384. \r\n
    385.             return this;
    386. \r\n
    387.         }
    388. \r\n
    389. \r\n
    390.         /// <summary>For a description of this member, see <see cref=\"M:System.IConvertible.ToChar(System.IFormatProvider)\" />. </summary>
    391. \r\n
    392.         /// <returns>The value of the current instance, converted to a <see cref=\"T:System.Char\" />.</returns>
    393. \r\n
    394.         /// <param name=\"provider\">This parameter is ignored.</param>
    395. \r\n
    396.         char System.IConvertible.ToChar(IFormatProvider provider)
    397. \r\n
    398.         {
    399. \r\n
    400.             return Convert.ToChar(this);
    401. \r\n
    402.         }
    403. \r\n
    404. \r\n
    405.         /// <summary>This conversion is not supported. Attempting to use this method throws an <see cref=\"T:System.InvalidCastException\" />.</summary>
    406. \r\n
    407.         /// <returns>This conversion is not supported. No value is returned.</returns>
    408. \r\n
    409.         /// <param name=\"provider\">This parameter is ignored.</param>
    410. \r\n
    411.         /// <exception cref=\"T:System.InvalidCastException\">In all cases.</exception>
    412. \r\n
    413.         DateTime System.IConvertible.ToDateTime(IFormatProvider provider)
    414. \r\n
    415.         {
    416. \r\n
    417.             object[] objArray = new object[] { \"Byte\"\"DateTime\" };
    418. \r\n
    419.             throw new InvalidCastException(Environment.GetResourceString(\"InvalidCast_FromTo\", objArray));
    420. \r\n
    421.         }
    422. \r\n
    423. \r\n
    424.         /// <summary>For a description of this member, see <see cref=\"M:System.IConvertible.ToDecimal(System.IFormatProvider)\" />. </summary>
    425. \r\n
    426.         /// <returns>The value of the current instance, converted to a <see cref=\"T:System.Decimal\" />.</returns>
    427. \r\n
    428.         /// <param name=\"provider\">This parameter is ignored.</param>
    429. \r\n
    430.         decimal System.IConvertible.ToDecimal(IFormatProvider provider)
    431. \r\n
    432.         {
    433. \r\n
    434.             return Convert.ToDecimal(this);
    435. \r\n
    436.         }
    437. \r\n
    438. \r\n
    439.         /// <summary>For a description of this member, see <see cref=\"M:System.IConvertible.ToDouble(System.IFormatProvider)\" />. </summary>
    440. \r\n
    441.         /// <returns>The value of the current instance, converted to a <see cref=\"T:System.Double\" />.</returns>
    442. \r\n
    443.         /// <param name=\"provider\">This parameter is ignored.</param>
    444. \r\n
    445.         double System.IConvertible.ToDouble(IFormatProvider provider)
    446. \r\n
    447.         {
    448. \r\n
    449.             return Convert.ToDouble(this);
    450. \r\n
    451.         }
    452. \r\n
    453. \r\n
    454.         /// <summary>For a description of this member, see <see cref=\"M:System.IConvertible.ToInt16(System.IFormatProvider)\" />. </summary>
    455. \r\n
    456.         /// <returns>The value of the current instance, converted to an <see cref=\"T:System.Int16\" />.</returns>
    457. \r\n
    458.         /// <param name=\"provider\">This parameter is ignored.</param>
    459. \r\n
    460.         short System.IConvertible.ToInt16(IFormatProvider provider)
    461. \r\n
    462.         {
    463. \r\n
    464.             return Convert.ToInt16(this);
    465. \r\n
    466.         }
    467. \r\n
    468. \r\n
    469.         /// <summary>For a description of this member, see <see cref=\"M:System.IConvertible.ToInt32(System.IFormatProvider)\" />. </summary>
    470. \r\n
    471.         /// <returns>The value of the current instance, converted to an <see cref=\"T:System.Int32\" />.</returns>
    472. \r\n
    473.         /// <param name=\"provider\">This parameter is ignored.</param>
    474. \r\n
    475.         int System.IConvertible.ToInt32(IFormatProvider provider)
    476. \r\n
    477.         {
    478. \r\n
    479.             return Convert.ToInt32(this);
    480. \r\n
    481.         }
    482. \r\n
    483. \r\n
    484.         /// <summary>For a description of this member, see <see cref=\"M:System.IConvertible.ToInt64(System.IFormatProvider)\" />. </summary>
    485. \r\n
    486.         /// <returns>The value of the current instance, converted to an <see cref=\"T:System.Int64\" />.</returns>
    487. \r\n
    488.         /// <param name=\"provider\">This parameter is ignored.</param>
    489. \r\n
    490.         long System.IConvertible.ToInt64(IFormatProvider provider)
    491. \r\n
    492.         {
    493. \r\n
    494.             return Convert.ToInt64(this);
    495. \r\n
    496.         }
    497. \r\n
    498. \r\n
    499.         /// <summary>For a description of this member, see <see cref=\"M:System.IConvertible.ToSByte(System.IFormatProvider)\" />. </summary>
    500. \r\n
    501.         /// <returns>The value of the current instance, converted to an <see cref=\"T:System.SByte\" />.</returns>
    502. \r\n
    503.         /// <param name=\"provider\">This parameter is ignored.</param>
    504. \r\n
    505.         sbyte System.IConvertible.ToSByte(IFormatProvider provider)
    506. \r\n
    507.         {
    508. \r\n
    509.             return Convert.ToSByte(this);
    510. \r\n
    511.         }
    512. \r\n
    513. \r\n
    514.         /// <summary>For a description of this member, see <see cref=\"M:System.IConvertible.ToSingle(System.IFormatProvider)\" />. </summary>
    515. \r\n
    516.         /// <returns>The value of the current instance, converted to a <see cref=\"T:System.Single\" />.</returns>
    517. \r\n
    518.         /// <param name=\"provider\">This parameter is ignored.</param>
    519. \r\n
    520.         float System.IConvertible.ToSingle(IFormatProvider provider)
    521. \r\n
    522.         {
    523. \r\n
    524.             return Convert.ToSingle(this);
    525. \r\n
    526.         }
    527. \r\n
    528. \r\n
    529.         /// <summary>For a description of this member, see <see cref=\"M:System.IConvertible.ToType(System.Type,System.IFormatProvider)\" />. </summary>
    530. \r\n
    531.         /// <returns>The value of the current instance, converted to <paramref name=\"type\" />.</returns>
    532. \r\n
    533.         /// <param name=\"type\">The type to which to convert this <see cref=\"T:System.Byte\" /> value. </param>
    534. \r\n
    535.         /// <param name=\"provider\">An <see cref=\"T:System.IFormatProvider\" /> implementation that supplies information about the format of the returned value.</param>
    536. \r\n
    537.         /// <exception cref=\"T:System.ArgumentNullException\">
    538. \r\n
    539.         ///   <paramref name=\"type\" /> is null. </exception>
    540. \r\n
    541.         /// <exception cref=\"T:System.InvalidCastException\">The requested type conversion is not supported. </exception>
    542. \r\n
    543.         object System.IConvertible.ToType(Type type, IFormatProvider provider)
    544. \r\n
    545.         {
    546. \r\n
    547.             return Convert.DefaultToType(this, type, provider);
    548. \r\n
    549.         }
    550. \r\n
    551. \r\n
    552.         /// <summary>For a description of this member, see <see cref=\"M:System.IConvertible.ToUInt16(System.IFormatProvider)\" />.</summary>
    553. \r\n
    554.         /// <returns>The value of the current instance, converted to a <see cref=\"T:System.UInt16\" />.</returns>
    555. \r\n
    556.         /// <param name=\"provider\">This parameter is ignored.</param>
    557. \r\n
    558.         ushort System.IConvertible.ToUInt16(IFormatProvider provider)
    559. \r\n
    560.         {
    561. \r\n
    562.             return Convert.ToUInt16(this);
    563. \r\n
    564.         }
    565. \r\n
    566. \r\n
    567.         /// <summary>For a description of this member, see <see cref=\"M:System.IConvertible.ToUInt32(System.IFormatProvider)\" />.</summary>
    568. \r\n
    569.         /// <returns>The value of the current instance, converted to a <see cref=\"T:System.UInt32\" />.</returns>
    570. \r\n
    571.         /// <param name=\"provider\">This parameter is ignored.</param>
    572. \r\n
    573.         uint System.IConvertible.ToUInt32(IFormatProvider provider)
    574. \r\n
    575.         {
    576. \r\n
    577.             return Convert.ToUInt32(this);
    578. \r\n
    579.         }
    580. \r\n
    581. \r\n
    582.         /// <summary>For a description of this member, see <see cref=\"M:System.IConvertible.ToUInt64(System.IFormatProvider)\" />.</summary>
    583. \r\n
    584.         /// <returns>The value of the current instance, converted to a <see cref=\"T:System.UInt64\" />.</returns>
    585. \r\n
    586.         /// <param name=\"provider\">This parameter is ignored.</param>
    587. \r\n
    588.         ulong System.IConvertible.ToUInt64(IFormatProvider provider)
    589. \r\n
    590.         {
    591. \r\n
    592.             return Convert.ToUInt64(this);
    593. \r\n
    594.         }
    595. \r\n
    596. \r\n
    597.         /// <summary>Converts the value of the current <see cref=\"T:System.Byte\" /> object to its equivalent string representation.</summary>
    598. \r\n
    599.         /// <returns>The string representation of the value of this object, which consists of a sequence of digits that range from 0 to 9 with no leading zeroes.</returns>
    600. \r\n
    601.         /// <filterpriority>1</filterpriority>
    602. \r\n
    603.         [__DynamicallyInvokable]
    604. \r\n
    605.         [SecuritySafeCritical]
    606. \r\n
    607.         public override string ToString()
    608. \r\n
    609.         {
    610. \r\n
    611.             return Number.FormatInt32((int)thisnull, NumberFormatInfo.CurrentInfo);
    612. \r\n
    613.         }
    614. \r\n
    615. \r\n
    616.         /// <summary>Converts the value of the current <see cref=\"T:System.Byte\" /> object to its equivalent string representation using the specified format.</summary>
    617. \r\n
    618.         /// <returns>The string representation of the current <see cref=\"T:System.Byte\" /> object, formatted as specified by the <paramref name=\"format\" /> parameter.</returns>
    619. \r\n
    620.         /// <param name=\"format\">A numeric format string.</param>
    621. \r\n
    622.         /// <exception cref=\"T:System.FormatException\">
    623. \r\n
    624.         ///   <paramref name=\"format\" /> includes an unsupported specifier. Supported format specifiers are listed in the Remarks section.</exception>
    625. \r\n
    626.         /// <filterpriority>1</filterpriority>
    627. \r\n
    628.         [__DynamicallyInvokable]
    629. \r\n
    630.         [SecuritySafeCritical]
    631. \r\n
    632.         public string ToString(string format)
    633. \r\n
    634.         {
    635. \r\n
    636.             return Number.FormatInt32((int)this, format, NumberFormatInfo.CurrentInfo);
    637. \r\n
    638.         }
    639. \r\n
    640. \r\n
    641.         /// <summary>Converts the numeric value of the current <see cref=\"T:System.Byte\" /> object to its equivalent string representation using the specified culture-specific formatting information.</summary>
    642. \r\n
    643.         /// <returns>The string representation of the value of this object in the format specified by the <paramref name=\"provider\" /> parameter.</returns>
    644. \r\n
    645.         /// <param name=\"provider\">An object that supplies culture-specific formatting information.</param>
    646. \r\n
    647.         /// <filterpriority>1</filterpriority>
    648. \r\n
    649.         [__DynamicallyInvokable]
    650. \r\n
    651.         [SecuritySafeCritical]
    652. \r\n
    653.         public string ToString(IFormatProvider provider)
    654. \r\n
    655.         {
    656. \r\n
    657.             return Number.FormatInt32((int)thisnull, NumberFormatInfo.GetInstance(provider));
    658. \r\n
    659.         }
    660. \r\n
    661. \r\n
    662.         /// <summary>Converts the value of the current <see cref=\"T:System.Byte\" /> object to its equivalent string representation using the specified format and culture-specific formatting information.</summary>
    663. \r\n
    664.         /// <returns>The string representation of the current <see cref=\"T:System.Byte\" /> object, formatted as specified by the <paramref name=\"format\" /> and <paramref name=\"provider\" /> parameters.</returns>
    665. \r\n
    666.         /// <param name=\"format\">A standard or custom numeric format string.</param>
    667. \r\n
    668.         /// <param name=\"provider\">An object that supplies culture-specific formatting information.</param>
    669. \r\n
    670.         /// <exception cref=\"T:System.FormatException\">
    671. \r\n
    672.         ///   <paramref name=\"format\" /> includes an unsupported specifier. Supported format specifiers are listed in the Remarks section.</exception>
    673. \r\n
    674.         /// <filterpriority>1</filterpriority>
    675. \r\n
    676.         [__DynamicallyInvokable]
    677. \r\n
    678.         [SecuritySafeCritical]
    679. \r\n
    680.         public string ToString(string format, IFormatProvider provider)
    681. \r\n
    682.         {
    683. \r\n
    684.             return Number.FormatInt32((int)this, format, NumberFormatInfo.GetInstance(provider));
    685. \r\n
    686.         }
    687. \r\n
    688. \r\n
    689.         /// <summary>Tries to convert the string representation of a number to its <see cref=\"T:System.Byte\" /> equivalent, and returns a value that indicates whether the conversion succeeded.</summary>
    690. \r\n
    691.         /// <returns>true if <paramref name=\"s\" /> was converted successfully; otherwise, false. </returns>
    692. \r\n
    693.         /// <param name=\"s\">A string that contains a number to convert. The string is interpreted using the <see cref=\"F:System.Globalization.NumberStyles.Integer\" /> style.</param>
    694. \r\n
    695.         /// <param name=\"result\">When this method returns, contains the <see cref=\"T:System.Byte\" /> value equivalent to the number contained in <paramref name=\"s\" /> if the conversion succeeded, or zero if the conversion failed. This parameter is passed uninitialized.</param>
    696. \r\n
    697.         /// <filterpriority>1</filterpriority>
    698. \r\n
    699.         [__DynamicallyInvokable]
    700. \r\n
    701.         public static bool TryParse(string s, out byte result)
    702. \r\n
    703.         {
    704. \r\n
    705.             return byte.TryParse(s, NumberStyles.Integer, NumberFormatInfo.CurrentInfo, out result);
    706. \r\n
    707.         }
    708. \r\n
    709. \r\n
    710.         /// <summary>Converts the string representation of a number in a specified style and culture-specific format to its <see cref=\"T:System.Byte\" /> equivalent. A return value indicates whether the conversion succeeded or failed.</summary>
    711. \r\n
    712.         /// <returns>true if <paramref name=\"s\" /> was converted successfully; otherwise, false.</returns>
    713. \r\n
    714.         /// <param name=\"s\">A string containing a number to convert. The string is interpreted using the style specified by <paramref name=\"style\" />. </param>
    715. \r\n
    716.         /// <param name=\"style\">A bitwise combination of <see cref=\"T:System.Globalization.NumberStyles\" /> values that indicates the style elements that can be present in <paramref name=\"s\" />. A typical value to specify is <see cref=\"F:System.Globalization.NumberStyles.Integer\" />.</param>
    717. \r\n
    718.         /// <param name=\"provider\">An <see cref=\"T:System.IFormatProvider\" /> object that supplies culture-specific formatting information about <paramref name=\"s\" />. If <paramref name=\"provider\" /> is null, the thread current culture is used. </param>
    719. \r\n
    720.         /// <param name=\"result\">When this method returns, contains the 8-bit unsigned integer value equivalent to the number contained in <paramref name=\"s\" /> if the conversion succeeded, or zero if the conversion failed. The conversion fails if the <paramref name=\"s\" /> parameter is null, is not of the correct format, or represents a number less than <see cref=\"F:System.Byte.MinValue\" /> or greater than <see cref=\"F:System.Byte.MaxValue\" />. This parameter is passed uninitialized. </param>
    721. \r\n
    722.         /// <exception cref=\"T:System.ArgumentException\">
    723. \r\n
    724.         ///   <paramref name=\"style\" /> is not a <see cref=\"T:System.Globalization.NumberStyles\" /> value. -or-<paramref name=\"style\" /> is not a combination of <see cref=\"F:System.Globalization.NumberStyles.AllowHexSpecifier\" /> and <see cref=\"F:System.Globalization.NumberStyles.HexNumber\" /> values.</exception>
    725. \r\n
    726.         /// <filterpriority>1</filterpriority>
    727. \r\n
    728.         [__DynamicallyInvokable]
    729. \r\n
    730.         public static bool TryParse(string s, NumberStyles style, IFormatProvider provider, out byte result)
    731. \r\n
    732.         {
    733. \r\n
    734.             NumberFormatInfo.ValidateParseStyleInteger(style);
    735. \r\n
    736.             return byte.TryParse(s, style, NumberFormatInfo.GetInstance(provider), out result);
    737. \r\n
    738.         }
    739. \r\n
    740. \r\n
    741.         private static bool TryParse(string s, NumberStyles style, NumberFormatInfo info, out byte result)
    742. \r\n
    743.         {
    744. \r\n
    745.             int num;
    746. \r\n
    747.             result = 0;
    748. \r\n
    749.             if (!Number.TryParseInt32(s, style, info, out num))
    750. \r\n
    751.             {
    752. \r\n
    753.                 return false;
    754. \r\n
    755.             }
    756. \r\n
    757.             if (num < 0 || num > 255)
    758. \r\n
    759.             {
    760. \r\n
    761.                 return false;
    762. \r\n
    763.             }
    764. \r\n
    765.             result = (byte)num;
    766. \r\n
    767.             return true;
    768. \r\n
    769.         }
    770. \r\n
    771.     }
    772. \r\n
    773. }
    774. \r\n
    \r\n
    \r\n

    示例

    \r\n未完待续', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6286, 'c%e5%ad%a6%e4%b9%a0%e7%ac%94%e8%ae%b0004%ef%bc%9aobject%e7%b1%bb%e8%af%a6%e8%a7%a3', 'c#学习笔记004:Object类详解', '2012-12-22 15:34:36', '2019-03-25 21:29:22', '
    概述\r\n====\r\n\r\nObject类对于我们来说,既熟悉又陌生。他是C#所有类的基类,因此有必要深入去探究。\r\n\r\nMSDN\r\n====\r\n\r\n\r\n\r\n源码\r\n====\r\n\r\n \r\n\r\n方法详解\r\n========\r\n\r\n \r\n
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6321, 'using-windows-live-writer-to-write-blog', '使用Windows Live Writer写博客', '2013-10-01 09:37:00', '2019-03-25 21:29:22', '

    概述

    \r\n未完待续\r\n

    下载

    \r\nhttp://windows.microsoft.com/zh-cn/windows-live/essentials\r\n\r\n ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6330, 'crm-development-note-001-overall-demand-analysis', 'CRM项目开发笔记001:整体需求分析', '2014-07-01 17:07:01', '2019-03-25 21:29:22', '未完待续', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6336, '20141223232454', '20141223232454', '2014-12-23 15:24:56', '2019-03-25 21:29:22', '时间再紧,也要出精品。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6343, '%e3%80%8a%e7%ae%97%e6%b3%95%e5%af%bc%e8%ae%ba%e3%80%8b%e9%98%85%e8%af%bb%e7%ac%94%e8%ae%b0001%ef%bc%9a%e6%8f%92%e5%85%a5%e6%8e%92%e5%ba%8f', '《算法导论》阅读笔记001:插入排序', '2014-12-23 16:08:02', '2019-03-25 21:29:22', '原地排序\r\n循环不变式', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6345, 'struts2%e6%95%99%e7%a8%8b', 'Struts2教程', '2012-12-23 16:08:00', '2019-03-25 21:29:22', 'Struts2教程1:第一个Struts2程序', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6347, '%e5%ae%89%e5%8d%93%e5%8a%a8%e7%94%bb%e5%ad%a6%e4%b9%a0', '安卓动画学习', '2013-12-23 16:08:00', '2019-03-25 21:29:22', 'http://www.eoeandroid.com/thread-653-1-1.html', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6349, 'struts1-x%e7%b3%bb%e5%88%97%e6%95%99%e7%a8%8b', 'Struts1.x系列教程', '2011-12-23 16:09:00', '2019-03-25 21:29:22', 'Struts1.x系列教程(1):用MyEclipse开发第一个Struts程序', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6351, 'sql-server-learning-note-024-and-jointly-constructing-a-delimited-string-into-a-temporary-table', 'SQL Server学习笔记024:构造分隔字符串并联合成临时表', '2014-12-24 04:37:02', '2019-03-25 21:29:22', '

    代码如下

    \r\n
    \r\n
      \r\n
    1. ----------------更新商品的库存量开始------------------
    2. \r\n
    3.                 --更新商品的库存跟skumap,这个是无论订单在什么状态下都要执行的
    4. \r\n
    5.                 --更新商品的库存量,跟盘点库存共用一个存储过程
    6. \r\n
    7.                 --exec XpProc_ProductStorage_Update @orderid,1
    8. \r\n
    9.                 select @productids=@productids+\',\'+cast(productid as varchar),
    10. \r\n
    11.                 @goodsids=@goodsids+\',\'+cast(goodsid as varchar),@quantitys=@quantitys+\',\'+cast(quantity as varchar),@send_quantitys=@send_quantitys+\',\'+cast(quantity-stockout as varchar)
    12. \r\n
    13.                 from orderproduct (nolock) where orderid=@orderid
    14. \r\n
    15.                 select @productids=stuff(@productids,1,1,\'\'), @goodsids=stuff(@goodsids,1,1,\'\'), @quantitys=stuff(@quantitys,1,1,\'\')
    16. \r\n
    17.                 --exec XpProc_ProductStorage_Update @productids,@goodsids,@quantitys,1
    18. \r\n
    19.                 --测试
    20. \r\n
    21.                 --declare @msg varchar(8000)
    22. \r\n
    23.                 --set @msg=\'productids:\'+@productids+\' goodsids:\'+@goodsids+\' quantitys:\'+@quantitys
    24. \r\n
    25.                 --将商品id,货品id,购买数量id连接成一个临时表
    26. \r\n
    27.                 select a.value as \'productid\',b.value as \'goodsid\',c.value as \'quantity\'
    28. \r\n
    29.                 into #groupgoods
    30. \r\n
    31.                 from
    32. \r\n
    33.                 (select * from dbo.SplitToTable_Func(@productids,\',\'))a,
    34. \r\n
    35.                 (select *from dbo.SplitToTable_Func(@goodsids,\',\'))b,
    36. \r\n
    37.                 (select *from dbo.func_splitint2(@quantitys))c
    38. \r\n
    39.                 where a.id=b.id and a.id=c.id
    40. \r\n
    41.                 --更新锁库存
    42. \r\n
    43.                 --select g.productid,g.goodsid,s.lockstorage,gp.quantity,* 
    44. \r\n
    45.                 update s set s.lockstorage=s.lockstorage-gp.quantity
    46. \r\n
    47.                 from goods g(nolock),#groupgoods gp
    48. \r\n
    49.                 LEFT JOIN goodslockstorage s ON s.goodsid=gp.goodsid AND s.ztdno=@ztdno
    50. \r\n
    51.                 where g.goodsid=gp.goodsid
    52. \r\n
    53.                 --exec logger @msg
    54. \r\n
    55.                 --return
    56. \r\n
    57.                 ----------------更新商品的库存量结束------------------
    58. \r\n
    \r\n
    \r\n ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6354, 'create-shell-script-linux', 'Linux创建shell脚本', '2014-12-24 05:35:06', '2019-03-25 21:29:22', '
    \r\n
    \r\n

    对shell的认识

    \r\nshell不仅是命令的收集,也是一门强大的编程语言(使大量的任务自动化,擅长系统管理任务,特别是那些易用性,可维护性,便携性比效率更重要的任务)\r\n

    开始创建一个脚本

    \r\n我们使用bash(bourne/目的地,边界/ again shell)\r\n\r\n使用gedit编辑器编写,或者vi等,依据个人习惯;在文件的第一行,以下面的内容开始:\r\n\r\n#!\r\n\r\n
    \r\n
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6356, 'libcurl-note-001-study-on-libcurl', 'Libcurl学习笔记001:初探libcurl', '2014-12-24 06:46:08', '2019-03-25 21:29:22', '

    \r\n 前言1
    \r\n

    \r\n

    \r\n 一直想写一个CSDN下载器,一直没有时间。之前到时用.NET和Java的类库写过http模拟请求(详见我写的中国铁通充值接口的文章),不过感觉用着还是不过顺手。早就听说了CURL,不过今天一试,才知道它的强大。\r\n

    \r\n

    \r\n CURL官方网站
    \r\n

    \r\n

    \r\n http://www.curl.haxx.se/\r\n

    \r\n

    \r\n CURL简介
    \r\ncurl是利用URL语法在命令行方式下工作的开源文件传输工具。它被广泛应用在Unix、多种Linux发行版中,并且有DOS和Win32、Win64下的移植版本。\r\n

    \r\n

    \r\n
    \r\n

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6363, '001-xpshop2012-the-download-installation-and-configuration', '001 Xpshop2012的下载安装与配置', '2014-12-03 05:52:09', '2019-03-26 00:10:02', '

    Xpshop简介

    \r\n

    下载

    \r\n

    安装与配置

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6369, '101-xpvshop%e7%9a%84%e6%95%b4%e4%bd%93%e7%bb%93%e6%9e%84%e5%88%86%e6%9e%90', '101 XpVShop的整体结构分析', '2014-12-02 07:03:00', '2019-03-25 21:29:22', '\"2014-12-25_142330\"', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6417, 'special', '专题', '2011-09-10 11:47:43', '2019-12-01 21:48:39', '精华\r\n====\r\n\r\n[Struts2.3.4.1 Spring3.2.3 Hibernate4.1.9_配置步骤](http://www.terwer.com/ssh2.html)\r\n\r\n.NET日志记录框架Log4Net使用总结](http://www.terwer.com/net-log4net-logging-framework-summary.html)\r\n\r\nJava系列\r\n========\r\n\r\nJavaSE系列\r\n----------\r\n\r\n1 [Java学习笔记001:【1.1】Win7下JDK的下载与安装、第一个Java程序的编译与执行](http://www.terwer.com/java-learning-notes-001-1-0-introduction-to-java-se-download-and-install-jdk-first-compilation-and-execution-of-java-programs-java-programs.html)\r\n\r\n1 Java学习笔记001:【1.2】CentOS下JDK的下载与安装、第一个Java程序的编译与执行\r\n\r\n1[ 重拾Java学习笔记001:java中的关键字](http://www.terwer.com/java-keywords-in-the-study-notes-001.html)\r\n\r\n2 [重拾Java学习笔记001:【1.1】用Java在记事本中写一个最简单的HelloWorld程序](http://www.terwer.com/java-again-learn-note-001-1-1-in-notepad-write-a-simple-helloworld-java-program.html)\r\n\r\n3 [Java学习笔记001-【1.2】一个简单的Applet程序](http://www.terwer.com/a-simple-applet.html)\r\n\r\n4 [重拾Java学习笔记001:【1.3】重温GUI形式的Hello world](http://www.terwer.com/java-again-learn-note-001-1-3-reliving-gui-hello-world.html)\r\n\r\n5 [重拾Java学习笔记002:java中的注解深度剖析](http://www.terwer.com/back-to-java-study-notes-002java-notes-in-depth-analysis.html)\r\n\r\n6 重拾Java学习笔记003:深度剖析Java中的匿名内部类\r\n\r\n7 [重拾Java学习笔记004:Java泛型高级进阶](http://www.terwer.com/restore-java-study-notes-004java-a-generic-high-advanced.html)\r\n\r\n8 [重拾Java学习笔记005:解读Java中的Object类](http://www.terwer.com/restore-java-learning-notes-005-interpretation-of-object-classes-in-java.html)\r\n\r\n9 重拾Java学习笔记006:Java集合框架\r\n\r\n10 重拾Java学习笔记007:Java获取Class对象的三种方法\r\n\r\n11 重拾Java学习笔记008:Java反射的四大功能\r\n\r\n12 重拾Java学习笔记009:浅拷贝示意图\r\n\r\n \r\n\r\nJavaEE系列\r\n==========\r\n\r\nStruts\r\n------\r\n\r\nStruts2\r\n-------\r\n\r\nHibernate\r\n---------\r\n\r\nMybatits\r\n--------\r\n\r\nSpring\r\n------\r\n\r\n050 [Spring学习笔记050:Spring MVC入门:Hello World](http://www.terwer.com/spring-learning-notes-050-getting-started-with-spring-mvc-hello-worldo.html)\r\n\r\nMaven系列\r\n---------\r\n\r\n001 Maven学习笔记001:Maven实战(一)安装和配置\r\n\r\n002 Maven学习笔记002:Maven 手动添加 JAR 包到本地仓库\r\n\r\n003 Maven学习笔记003:maven项目的标准目录结构\r\n\r\nAndroid系列\r\n===========\r\n\r\n024 [Android学习笔记004: Android 进程生命周期 Process Lifecycle](http://www.terwer.com/android-learning-notes-004-android-process-life-cycle.html)\r\n\r\n025 Intel Atom Android模拟器的安装与配置\r\n\r\n026 Failed to allocate memory: 8 (andriod模拟器无法启动)\r\n\r\n027 Android Studio解决Fetching android sdk component information加载过久问题\r\n\r\n028 [Android模拟器(AVD)快捷键](http://www.terwer.com/android-emulator-avd-shortcuts.html)\r\n\r\n.NET MVC系列\r\n============\r\n\r\n1 [Asp .Net Mvc4学习笔记010:ASP.NET MVC 的依赖注入](http://www.terwer.com/asp-net-mvc4-study-notes-004-asp-net-mvc-dependency-injection.html)\r\n\r\n2\r\n\r\n3\r\n\r\nC#系列\r\n=======\r\n\r\n.NET 2/3.5\r\n----------\r\n\r\n004 [c#学习笔记004:Object类详解](http://www.terwer.com/c学习笔记004:object类详解.html)\r\n\r\n005 [c#学习笔记005:Byte数据类型](http://www.terwer.com/c-learning-notes-005byte-data-types.html)\r\n\r\n006 [c#学习笔记006:c#中const与readonly区别](http://www.terwer.com/learning-csharp-note-006-c-difference-between-const-and-readonly.html)\r\n\r\n.NET 4.0/4.5\r\n------------\r\n\r\n.NET Core 5\r\n-----------\r\n\r\n001 [.NET Core 5学习笔记001:拥抱开源时代](http://www.terwer.com/net-core-5-learn-note-001-embracing-the-open-source-era.html)\r\n\r\n设计模式系列\r\n============\r\n\r\n算法系列\r\n========\r\n\r\n数据库系列\r\n==========\r\n\r\nSQL Server系列\r\n--------------\r\n\r\n1 [《SQL必知必会》阅读笔记](http://www.terwer.com/the-sql-must-know-it-will-read-the-notes.html)\r\n\r\n20 SQL Sever学习笔记020:写日志与清空日志\r\n\r\n21 SQL Server学习笔记021:LEFT JOIN\r\n\r\n22 [SQL Server学习笔记022:多表关联批量更新](http://www.terwer.com/sql-server-learning-note-022-associated-bulk-updates.html)\r\n\r\n23 [SQL Server学习笔记023:批量插入](http://www.terwer.com/sql-server-learning-notes-023-bulk-insert.html)\r\n\r\n24 [SQL Server学习笔记024:构造分隔字符串并联合成临时表](http://www.terwer.com/sql-server-learning-note-024-and-jointly-constructing-a-delimited-string-into-a-temporary-table.html)\r\n\r\n25 SQL Server学习笔记025:构造使用WHERE IN子句的动态Transact-SQL方法进行编号查询\r\n\r\n26 SQL Server学习笔记026:SQL SERVER 用sql语句将一列数据拼接成一个字符串\r\n\r\n27 [SQL Server学习笔记027:多行转换为一行](http://www.terwer.com/sql-server-learning-notes-027-multiple-rows-into-one.html)\r\n\r\n28 [SQL Server学习笔记028:SQL Server实现Split函数将字符串分隔转换成数据表](http://www.terwer.com/sql-server-implement-a-split-function-to-convert-a-string-to-separate-the-data-table.html)\r\n\r\n29 [SQL Server学习笔记029:SQL Server使用表变量解决不能在函数内使用临时表的问题](http://www.terwer.com/sql-server-solution-not-within-a-function-using-table-variables-use-temporary-table-problems.html)\r\n\r\n30 [SQL Server学习笔记030:深入理解SQL Server之nolock关键字](http://www.terwer.com/understanding-sql-server-keyword-nolock.html)\r\n\r\n31 [SQL Server学习笔记031:SQL Server使用常见误区](http://www.terwer.com/sql-server-uses-common-errors.html)\r\n\r\n32 [SQL Server学习笔记032:SQL SERVER使用游标构造SkuMap](http://www.terwer.com/sql-server-uses-a-cursor-structure-skumap.html)\r\n\r\nMySQL系列\r\n---------\r\n\r\nOracle系列\r\n----------\r\n\r\nORM系列\r\n=======\r\nEntityframework\r\n---------------\r\n040 [Entityframework中使用LINQ比较日期和时间](http://www.terwer.com/use-entityframework-linq-to-compare-date-and-time.html)\r\n\r\nWPF系列\r\n=======\r\n\r\nWPF学习笔记001:窗口居中\r\n\r\nWPF学习笔记002:从sender说开去\r\n\r\nWinform系列\r\n===========\r\n\r\nWinform学习笔记001:入口函数\r\n\r\nWinform学习笔记002:隐藏窗口边框和标题栏\r\n\r\nWinform学习笔记003:插入资源\r\n\r\n[Winform学习笔记004:窗口最小化](http://www.terwer.com/winform-study-notes-004-windows-minimize.html)\r\n\r\n[Winform学习笔记005:Winform中打开网页](http://www.terwer.com/winform-study-notes-open-page-in-005winform.html)\r\n\r\n[Winform学习笔记006:菜单鼠标移入移出效果](http://www.terwer.com/winform-study-notes-006-menu-move-the-mouse-to-move-the-effects.html)\r\n\r\n[Winform学习笔记007:菜单点击切换事件](http://www.terwer.com/winform-note-007-menu-click-the-toggle-event.html)\r\n\r\n版本控制系列\r\n============\r\n\r\nJQuery系列\r\n==========\r\n\r\n001 [JavaScript/JQuery插件化开发001:开篇](http://www.terwer.com/javascript-jquery-plugin-development-001-introduction.html)\r\n\r\nGIT\r\n---\r\n\r\n001 Git学习笔记001:Bonobo-Git-Server的安装与部署\r\n\r\nSVN\r\n---\r\n\r\n001 Svn学习笔记001:Subversion的安装与配置\r\n\r\n搜索引擎系列\r\n============\r\n\r\nLucene\r\n------\r\n\r\nLucene .NET\r\n-----------\r\n\r\n1 Apache Lucene .Net学习笔记001\r\n\r\nCURL\r\n----\r\n\r\n001 [Libcurl学习笔记001:初探libcurl](http://www.terwer.com/libcurl-note-001-study-on-libcurl.html)\r\n\r\nHTML5系列\r\n=========\r\n\r\n001 [浅谈HTML5之viewport标签](http://www.terwer.com/talking-about-the-viewport-of-the-html5-tag.html)\r\n\r\n源码分析系列\r\n============\r\n\r\n1 Bonobo-Git-Server\r\n-------------------\r\n\r\n001 Bonobo-Git-Server的简介、下载、安装与部署\r\n\r\n002 Bonobo-Git-Server整体架构分析\r\n\r\n003 Bonobo-Git-Server所用技术框架与类库评析\r\n\r\n2 jeecg\r\n-------\r\n\r\n3 petshop\r\n---------\r\n\r\n4 dtcms\r\n-------\r\n\r\n5 xpshop\r\n--------\r\n\r\n001 [Xpshop2012的下载安装与配置](http://www.terwer.com/001-xpshop2012-the-download-installation-and-configuration.html)\r\n\r\n002 Xpshop2012整体架构分析\r\n\r\n[003 XpShop数据库分析之Orders表:Orders](http://www.terwer.com/xpshop-analysis-003-database-orders-table-orders.html)\r\n\r\n[101 XpVShop的整体结构分析](http://www.terwer.com/101-xpvshop的整体结构分析.html)\r\n\r\n6 wordpress\r\n-----------\r\n\r\n项目开发系列\r\n============\r\n\r\nCRM项目\r\n-------\r\n\r\n001 CRM项目开发笔记001:整体需求分析\r\n\r\n招聘系统\r\n--------\r\n\r\n中国铁通充值借口\r\n----------------\r\n\r\n电商平台与微信商城\r\n------------------\r\n\r\n电商平台实战020:[电商平台实战之门店防伪码需求解决方案](http://www.terwer.com/e-commerce-platform-to-store-the-security-code-of-the-actual-demand-solutions.html)\r\n\r\n电商平台实战021:[电商平台实战之门店库存分配策略](http://www.terwer.com/actual-store-inventory-allocation-strategy-of-e-commerce-platform.html)\r\n\r\n电商平台实战022:[电商平台实战之库存与ERP对接解决方案](http://www.terwer.com/e-commerce-platform-to-combat-the-stock-dock-with-the-erp-solution.html)\r\n\r\n未完待续\r\n\r\n移动跨平台解决方案\r\n==================\r\n\r\nApache Cordova系列\r\n------------------\r\n\r\n001 Visual Studio 2013搭建Apache Cordova开发环境\r\n\r\nWindows批处理脚本\r\n=================\r\n\r\n001:CMD命令行输入与输出\r\n002:Hello Word:简单搞定curl模拟登陆\r\n\r\n正则表达式系列\r\n==============\r\n\r\n业余作品系列\r\n============\r\n\r\nAndroid二维码客户端-微码\r\n-----------------------\r\n\r\nJava实现网页爬虫抓取视频搜索\r\n---------------------------\r\n\r\n用Java实现视频地址解析\r\n----------------------\r\n\r\n001 [Spring MVC入门:Hello World](http://www.terwer.com/spring-learning-notes-050-getting-started-with-spring-mvc-hello-worldo.html)\r\n\r\n002 封装公用的Httphelper\r\n\r\n003 CKplayer的使用\r\n\r\n004 使用Httpwatch或fiddler跟踪http请求\r\n\r\n005 分析请求参数与http头\r\n\r\n006 分析参数中的加密算法\r\n\r\n007 尝试破解算法发送http请求\r\n\r\n008 验证结果与持续模拟\r\n\r\n009 集成测试\r\n\r\n\r\nJava实现云IDE\r\n-------------\r\n\r\nAndroid版聚合博客客户端\r\n-----------------------\r\n\r\n1.OneBlog Android版开发001:需求分析\r\n2.OneBlog Android版开发001:业务分析与原型设计\r\n3.界面设计\r\n4.服务端api设计\r\n\r\n* 4.1 [初探Wordpress XML-RPC api](http://www.terwer.com/study-on-the-wordpress-xml-rpc-api.html)\r\n\r\n5、交互设计\r\n* 5.1 [OneBlog开发系列之欢迎页面](http://www.terwer.com/oneblog-development-series-of-the-welcome-page.html)\r\n6、测试\r\n7、发布到商店\r\n\r\n\r\n项目架构系列\r\n============\r\n001 架构菜鸟成长之路之两层架构 - 回归本质\r\n002 架构菜鸟成长之路之经典三层 - 简单封装\r\n003 架构菜鸟成长之路之四层 - 轻量级\r\n004 架构菜鸟成长之路之n层 - 重量级(IOC、AOP)\r\n005 架构菜鸟成长之路之DDD - 领域驱动设计\r\n006 架构菜鸟成长之路之SOA - 面向服务的体系结构\r\n007 架构菜鸟成长之路之OSGI - 模块化架构\r\n007 架构菜鸟成长之路之 - 分布式架构\r\n。。。未完待续\r\n\r\n性能优化系列\r\n============\r\n\r\n算法研究系列\r\n============', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6440, 'taught-you-to-package-your-application-in-csharp-setup-unload-module-has-been-added', '手把手教你用C#打包应用程序(安装程序)【卸载模块已添加】', '2015-01-02 12:33:32', '2019-03-25 21:29:22', '

    \r\n 声明:
    \r\n软件平台:VisualStudio2005中文版(在03下操作雷同).\r\n

    \r\n

    \r\n 1:新建安装部署项目
    \r\n打开VS,点击新建项目,选择:其他项目类型->安装与部署->安装向导(安装项目也一样),然后点击确定.(详细见下图)\r\n

    \r\n

    \r\n
    \r\n2:安装向导

    \r\n关闭后打开安装向导,点击下一步,或者直接点击完成.
    \r\n如下图:\r\n

    \r\n

    \r\n 3:开始制作
    \r\n
    安装向导完成后即可进入项目文件夹:\r\n

    \r\n

    \r\n 双击\"应用程序文件夹\"在右边的空白处右击,选择添加->文件,将你的做的应用程序的可执行文件和相应的类库和组件添加进来.\r\n

    \r\n

    \r\n 然后右击你的可执行文件,创建快捷方式,然后把快捷方式分别剪切或复制到左边的\"用户的\'程序\'菜单\"和\"用户桌面\"中.
    \r\n这样安装程序安装安装完成后会在 \"开始->所有程序\"和\"桌面\"上生成程序的快捷方式.\r\n

    \r\n

    \r\n 然后右击左边的\"应用程序文件夹\"打开属性对话框:\r\n

    \r\n

    \r\n 将属性中的\"defaultlocation\"的路径中的\"[manufacturer]\"去掉,
    \r\n不然的话做好的安装程序默认安装目录会是\"c:programm file你的用户名安装解决方案名称\";
    \r\n修改后如图:\r\n

    \r\n

    \r\n 然后打开解决方案管理器,右击你的解决方案名称,选择属性:\r\n

    \r\n

    \r\n 在打开的属性页中,选择\"系统必备\",\r\n

    \r\n

    \r\n 在打开的系统必备页中,选中如下中的选择项,这个很重要!!!!!1!!!!!
    \r\n选上以后,在生成的安装文件包中包含.netframework组件.(这个选项默认是没有选中的)\r\n

    \r\n

    \r\n 好了,这样就完成99%了,然后点击\"生成->生成解决方案\",哈,生成成功!
    \r\n4:制作完成
    \r\n现在打开解决方案文件夹下的debug文件夹,就可以看到生成的安装文件了.\r\n

    \r\n

    \r\n 】关于\"卸载\"功能的添加
    \r\n上面的文章只介绍了简单的生成安装的方法,
    \r\n但是在vs.net2005下并没有直接生成卸载程序的功能,
    \r\n所以我们只好用msi来实现了,
    \r\n原理我就不讲了,网上一搜一堆,我只讲操作,
    \r\n
    1】:在添加你的应用程序项目的时候,多添加一个msiexec.exe进去,
    \r\n这个文件在c:windowssystem32文件夹下,\r\n

    \r\n

    \r\n 添加进去以后,为了让他更像个卸载程序,把他的名字改成\"Uninstall.exe\",\r\n

    \r\n

    \r\n 当然这个关系不大,改不改都行的.
    \r\n然后给他创建一个快捷方式,放到桌面或者\"开始-程序\"中,
    \r\n我选择放在了开始菜单中,然后下面我们要的做的就是查找这个部署项目的ProductCode了,
    \r\n鼠标左键单击项目名称,记住是左键单击,然后点击属性标签,注意:不是右击的属性,
    \r\n这个区别很大,这时你就可以看到ProductCode了,\r\n

    \r\n

    \r\n 然后打开你创建的那个快捷方式的属性对话框,
    \r\n在Aguements属性中输入\"/x {ProductCode}\",\r\n

    \r\n

    \r\n 好了,然后点击\"生成解决方案\"即可生成带有卸载功能的安装程序了.\r\n

    \r\n

    \r\n 制作到此结束,如有疑问,可以跟帖提出.
    \r\n如果我知道的话,就一定帮助大家解决问题.
    \r\n其实安装部署的制作也是博大精深的,
    \r\n在这里我也只是简单的教给大家制作一个简单的安装程序的方法.
    \r\n如果对这方面感兴趣的朋友,不妨多多的研究一下.
    \r\n共享你的新发现.\r\n

    \r\n

    \r\n 也希望喜欢的朋友多多的支持一下。\r\n

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6453, 'in-the-winform-added-to-the-textbox-text-boxes-ctrl-a-to-select-all-shortcut-keys', 'Winform学习笔记008:WinForm中,给TextBox文本框增加Ctrl A全选快捷键', '2015-01-02 13:50:03', '2019-03-25 21:29:22', '
    private void txtStatus_KeyDown    (object sender, KeyEventArgs e)\r\n{\r\nif (e.Modifiers == Keys.Control &amp;&amp; e.KeyCode == Keys.A)\r\n{\r\n    ((TextBox)sender).SelectAll();\r\n}\r\n}
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6467, '20150102223901', '20150102223901', '2015-01-02 14:39:03', '2019-03-25 21:29:22', '自己的博客终于折腾完了,可以安心写博客了。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6468, '20150102225330', '20150102225330', '2015-01-02 14:53:32', '2019-03-25 21:29:22', '每天必须把第二天的事列出来。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6470, 'csharp-to-determine-internal-ip-and-external-ip', 'C#判断内网ip和外网ip', '2015-01-03 08:27:44', '2019-03-25 21:29:22', '
        /// <summary>\r\n    /// 判断IP地址是否为内网IP地址\r\n    /// </summary>\r\n    /// <param name=\"ipAddress\">IP地址字符串</param>\r\n    /// <returns></returns>\r\n    private bool IsInnerIP(String ipAddress)\r\n    {\r\n        bool isInnerIp = false;\r\n        long ipNum = GetIpNum(ipAddress);\r\n        /**\r\n           私有IP:A类  10.0.0.0-10.255.255.255\r\n                   B类  172.16.0.0-172.31.255.255\r\n                   C类  192.168.0.0-192.168.255.255\r\n                   当然,还有127这个网段是环回地址\r\n          **/\r\n        long aBegin = GetIpNum(\"10.0.0.0\");\r\n        long aEnd = GetIpNum(\"10.255.255.255\");\r\n        long bBegin = GetIpNum(\"172.16.0.0\");\r\n        long bEnd = GetIpNum(\"172.31.255.255\");\r\n        long cBegin = GetIpNum(\"192.168.0.0\");\r\n        long cEnd = GetIpNum(\"192.168.255.255\");\r\n        isInnerIp = IsInner(ipNum, aBegin, aEnd) || IsInner(ipNum, bBegin, bEnd) || IsInner(ipNum, cBegin, cEnd) || ipAddress.Equals(\"127.0.0.1\");\r\n        return isInnerIp;\r\n    }\r\n    /// <summary>\r\n    /// 把IP地址转换为Long型数字\r\n    /// </summary>\r\n    /// <param name=\"ipAddress\">IP地址字符串</param>\r\n    /// <returns></returns>\r\n    private long GetIpNum(String ipAddress)\r\n    {\r\n        String[] ip = ipAddress.Split(\'.\');\r\n        long a = int.Parse(ip[0]);\r\n        long b = int.Parse(ip[1]);\r\n        long c = int.Parse(ip[2]);\r\n        long d = int.Parse(ip[3]);\r\n\r\n        long ipNum = a * 256 * 256 * 256 + b * 256 * 256 + c * 256 + d;\r\n        return ipNum;\r\n    }\r\n    /// <summary>\r\n    /// 判断用户IP地址转换为Long型后是否在内网IP地址所在范围\r\n    /// </summary>\r\n    /// <param name=\"userIp\"></param>\r\n    /// <param name=\"begin\"></param>\r\n    /// <param name=\"end\"></param>\r\n    /// <returns></returns>\r\n    private bool IsInner(long userIp, long begin, long end)\r\n    {\r\n        return (userIp >= begin) && (userIp <= end);\r\n    }
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6493, 'sql-server-learning-notes-025-structure-numbering-method-for-dynamic-transact-sql-queries-that-use-the-in-clause', 'SQL Server学习笔记025:构造使用WHERE IN子句的动态Transact-SQL方法进行编号查询', '2015-01-04 08:25:51', '2019-03-25 21:29:22', '
    \r\n
    --1. 构造使用IN子句的动态Transact-SQL方法进行编号查询
    \r\n
    \r\n
    --a. 要查询的字段类型是数字型
    \r\n
    \r\n
    --查询的值列表
    \r\n
    DECLARE @idlist varchar(100)
    \r\n
    SET @idlist=\'1,2,3\'
    \r\n
    \r\n
    --拼接并执行动态Transact-SQL语句
    \r\n
    EXEC(\'SELECT * FROM tbname WHERE fdname IN(\'+@idlist+\')\')
    \r\n
    GO
    \r\n
    \r\n
    --b. 要查询的字段类型是字符型
    \r\n
    --查询的值列表已经加上了字符串边界符
    \r\n
    DECLARE @idlist varchar(100)
    \r\n
    SET @idlist=\'\'\'a\'\',\'\'b\'\'\'\'a\'\',\'\'c\'\'\'
    \r\n
    \r\n
    --拼接并执行动态Transact-SQL语句
    \r\n
    EXEC(\'SELECT * FROM tbname WHERE fdname IN(\'+@idlist+\')\')
    \r\n
    GO
    \r\n
    \r\n
    --查询的值列表没有字符串边界符
    \r\n
    DECLARE @idlist varchar(100)
    \r\n
    SET @idlist=\'a,b\'\'a,c\'
    \r\n
    \r\n
    --由于是字段类型是,所以在拼接时,必须为其加上字符串边界符(\')
    \r\n
    DECLARE @s varchar(1000)
    \r\n
    SET @s=\'\'\'\'
    \r\n
        +REPLACE(REPLACE(@idlist,\'\'\'\',\'\'\'\'\'\'),\',\',\'\'\',\'\'\')
    \r\n
        +\'\'\'\'
    \r\n
    \r\n
    --拼接并执行动态Transact-SQL语句
    \r\n
    EXEC(\'SELECT * FROM tbname WHERE fdname IN(\'+@s+\')\')
    \r\n
    GO
    \r\n
    \r\n
    /*=====================================================*/
    \r\n
    \r\n
    \r\n
    --2. 使用LIKE或者PATINDEX进行编号查询
    \r\n
    --查询的值列表
    \r\n
    DECLARE @idlist varchar(100)
    \r\n
    SET @idlist=\'1,2,3\'
    \r\n
    \r\n
    --查询
    \r\n
    SELECT * FROM tbname WHERE CHARINDEX(\',\'+RTRIM(fdname)+\',\',\',\'+@idlist+\',\')>0
    \r\n
    SELECT * FROM tbname WHERE PATINDEX(\'%,\'+RTRIM(fdname)+\',%\',\',\'+@idlist+\',\')>0
    \r\n
    SELECT * FROM tbname WHERE \',\'+@idlist+\',\' LIKE \'%,\'+RTRIM(fdname)+\',%\'
    \r\n
    GO
    \r\n
    \r\n
    /*=====================================================*/
    \r\n
    \r\n
    \r\n
    --3. 编号查询中常见的错误
    \r\n
    --a. 最容易犯的错误:表达式充当表达式列表。
    \r\n
    DECLARE @s varchar(100)
    \r\n
    SET @s=\'1\'
    \r\n
    SELECT id,name FROM sysobjects WHERE id IN(@s)
    \r\n
    /*--结果
    \r\n
    id          name
    \r\n
    ---------------- ------------
    \r\n
    1           sysobjects
    \r\n
    --*/
    \r\n
    \r\n
    SET @s=\'1,2,3\'
    \r\n
    SELECT id,name FROM sysobjects WHERE id IN(@s)
    \r\n
    /*--结果
    \r\n
    服务器: 消息 245,级别 16,状态 1,行 3
    \r\n
    将 varchar 值 \'1,2,3\' 转换为数据类型为 int 的列时发生语法错误。
    \r\n
    --*/
    \r\n
    GO
    \r\n
    \r\n
    --b. 生成动态Transact-SQL语句时忽略了数据类型。
    \r\n
    DECLARE @s varchar(100)
    \r\n
    SET @s=\'U,S\'
    \r\n
    EXEC(\'SELECT id,name FROM sysobjects WHERE id IN(\'+@s+\')\')
    \r\n
    /*--结果:
    \r\n
    服务器: 消息 207,级别 16,状态 3,行 1
    \r\n
    列名 \'S\' 无效。
    \r\n
    服务器: 消息 207,级别 16,状态 1,行 1
    \r\n
    列名 \'U\' 无效。
    \r\n
    --*/
    \r\n
    GO
    \r\n
    \r\n
    --c. 忽略了比较的精确性问题。
    \r\n
    --要查询的数据
    \r\n
    DECLARE @t TABLE(col varchar(10))
    \r\n
    INSERT @t SELECT \'1\'
    \r\n
    UNION ALL SELECT \'11\'
    \r\n
    UNION ALL SELECT \'111\'
    \r\n
    UNION ALL SELECT \'22\'
    \r\n
    \r\n
    --查询
    \r\n
    DECLARE @s varchar(100)
    \r\n
    SET @s=\'111,22\'
    \r\n
    SELECT * FROM @t WHERE CHARINDEX(col,@s)>0
    \r\n
    /*--结果
    \r\n
    col
    \r\n
    ----------
    \r\n
    1
    \r\n
    11
    \r\n
    111
    \r\n
    22
    \r\n
    -*/
    \r\n
    GO
    \r\n
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6498, 'sql-server-learning-notes-026-sql-server-splicing-the-data-in-a-column-with-an-sql-statement-in-a-string', 'SQL Server学习笔记026:SQL SERVER 用sql语句将一列数据拼接成一个字符串', '2015-01-04 08:37:46', '2019-03-26 00:09:18', '

    \r\n 一行语句的解决方案\r\n

    \r\n
    \r\n
    \r\n 问题描述:\r\n
    \r\n
    \r\n 无论是在sql 2000,还是在 sql 2005 中,都没有提供字符串的聚合函数,\r\n
    \r\n
    \r\n   所以,当我们在处理下列要求时,会比较麻烦:\r\n
    \r\n
    \r\n 有表tb, 如下:\r\n
    \r\n
    \r\n id    value\r\n
    \r\n
    \r\n ----- ------\r\n
    \r\n
    \r\n 1     aa\r\n
    \r\n
    \r\n 1     bb\r\n
    \r\n
    \r\n 2     aaa\r\n
    \r\n
    \r\n 2     bbb\r\n
    \r\n
    \r\n 2     ccc\r\n
    \r\n
    \r\n 需要得到结果:\r\n
    \r\n
    \r\n id     values\r\n
    \r\n
    \r\n ------ -----------\r\n
    \r\n
    \r\n 1      aa,bb\r\n
    \r\n
    \r\n 2      aaa,bbb,ccc\r\n
    \r\n
    \r\n 即, group by id, 求 value 的和(字符串相加)\r\n
    \r\n
    \r\n  \r\n
    \r\n
    \r\n 1. 旧的解决方法\r\n
    \r\n
    \r\n  \r\n
    \r\n
    \r\n -- 1. 创建处理函数\r\n
    \r\n
    \r\n CREATE FUNCTION dbo.f_str(@id int)\r\n
    \r\n
    \r\n RETURNS varchar(8000)\r\n
    \r\n
    \r\n AS\r\n
    \r\n
    \r\n BEGIN\r\n
    \r\n
    \r\n     DECLARE @r varchar(8000)\r\n
    \r\n
    \r\n     SET @r = \'\'\r\n
    \r\n
    \r\n     SELECT @r = @r + \',\' + value\r\n
    \r\n
    \r\n     FROM tb\r\n
    \r\n
    \r\n     WHERE id=@id\r\n
    \r\n
    \r\n     RETURN STUFF(@r, 1, 1, \'\')\r\n
    \r\n
    \r\n END\r\n
    \r\n
    \r\n GO\r\n
    \r\n
    \r\n -- 调用函数\r\n
    \r\n
    \r\n  \r\n
    \r\n
    \r\n SELECt id, values=dbo.f_str(id) \r\n
    \r\n
    \r\n FROM tb \r\n
    \r\n
    \r\n GROUP BY id\r\n
    \r\n
    \r\n  \r\n
    \r\n
    \r\n -- 2. 新的解决方法 \r\n
    \r\n
    \r\n -- 示例数据\r\n
    \r\n
    \r\n DECLARE @t TABLE(id int, value varchar(10))\r\n
    \r\n
    \r\n INSERT @t SELECT 1, \'aa\'\r\n
    \r\n
    \r\n UNION ALL SELECT 1, \'bb\'\r\n
    \r\n
    \r\n UNION ALL SELECT 2, \'aaa\'\r\n
    \r\n
    \r\n UNION ALL SELECT 2, \'bbb\'\r\n
    \r\n
    \r\n UNION ALL SELECT 2, \'ccc\'\r\n
    \r\n
    \r\n  \r\n
    \r\n
    \r\n -- 查询处理\r\n
    \r\n
    \r\n SELECT *\r\n
    \r\n
    \r\n FROM(\r\n
    \r\n
    \r\n     SELECT DISTINCT \r\n
    \r\n
    \r\n         id\r\n
    \r\n
    \r\n     FROM @t\r\n
    \r\n
    \r\n )A\r\n
    \r\n
    \r\n OUTER APPLY(\r\n
    \r\n
    \r\n     SELECT \r\n
    \r\n
    \r\n         [values]= STUFF(REPLACE(REPLACE(\r\n
    \r\n
    \r\n             (\r\n
    \r\n
    \r\n                 SELECT value FROM @t N\r\n
    \r\n
    \r\n                 WHERE id = A.id\r\n
    \r\n
    \r\n                 FOR XML AUTO\r\n
    \r\n
    \r\n             ), \'<N value=\"\', \',\'), \'\"/>\', \'\'), 1, 1, \'\')\r\n
    \r\n
    \r\n )N\r\n
    \r\n
    \r\n  \r\n
    \r\n
    \r\n /*--结果\r\n
    \r\n
    \r\n id          values\r\n
    \r\n
    \r\n ----------- ----------------\r\n
    \r\n
    \r\n 1           aa,bb\r\n
    \r\n
    \r\n 2           aaa,bbb,ccc\r\n
    \r\n
    \r\n (2 行受影响)\r\n
    \r\n
    \r\n --*/\r\n
    \r\n
    \r\n  \r\n
    \r\n
    \r\n CSDN 社区帖子地址 \r\n
    \r\n
    \r\n  \r\n
    \r\n
    \r\n 附: 合并与分拆的CLR, sql2005的示例中有:\r\n
    \r\n
    \r\n 在安装sql 2005的示例后,默认安装目录为\r\n
    \r\n
    \r\n drive:Program FilesMicrosoft SQL Server90SamplesEngineProgrammabilityCLRStringUtilities中\r\n
    \r\n
    \r\n

    \r\n 多行语句的解决方案\r\n

    \r\n
    \r\n 执行\r\n
    \r\n
    \r\n SELECT userid FROM userinfo\r\n
    \r\n
    \r\n
    \r\n
    \r\n 得到\r\n
    \r\n
    \r\n 1\r\n
    \r\n
    \r\n 2\r\n
    \r\n
    \r\n 3\r\n
    \r\n
    \r\n 4\r\n
    \r\n
    \r\n
    \r\n
    \r\n 如果要得到\r\n
    \r\n
    \r\n 1,2,3,4\r\n
    \r\n
    \r\n
    \r\n
    \r\n 执行方案1\r\n
    \r\n
    \r\n DECLARE @STR VARCHAR(8000)\r\n
    \r\n
    \r\n SELECT @STR=ISNULL(@STR+\',\',\'\')+userid FROM (SELECT DISTINCT userid FROM userinfo)AS T\r\n
    \r\n
    \r\n SELECT @STR\r\n
    \r\n
    \r\n
    \r\n
    \r\n 执行方案2\r\n
    \r\n
    \r\n declare @output varchar(8000)\r\n
    \r\n
    \r\n select @output = coalesce(@output + \',\' , \'\') + userid from userinfo\r\n
    \r\n
    \r\n print @output\r\n
    \r\n

    \r\n  其他解决方案\r\n

    \r\n

    \r\n SQL 多行归并为一行的问题\r\n

    \r\n
    对于SQL Server 2005+版本的 使用FOR XML的方式 http://www.cnblogs.com/aolin/archive/2011/04/12/2014122.html
    \r\n
    对于MySQL使用 GROUP_CONCAT 函数 的方式进行处理\r\n对于Oracle使用 WMSYS.WM_CONCAT 函数 的方式进行处理\r\n
    \r\n

    \r\n  \r\n

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6507, 'sql-server-learning-notes-027-multiple-rows-into-one', 'SQL Server学习笔记027:多行转换为一行', '2015-01-04 09:05:09', '2019-03-26 00:09:07', '

    \r\n  \r\n

    \r\n

    \r\n 使用通常的方式测试表与测试数据\r\n

    \r\n

    \r\n CREATE TABLE TestTitle (\r\n

    \r\n

    \r\n name   VARCHAR(10),\r\n

    \r\n

    \r\n titleVARCHAR(10)\r\n

    \r\n

    \r\n );\r\n

    \r\n

    \r\n
    \r\n

    \r\n

    \r\n INSERT INTO TestTitle VALUES (\'张三\', \'程序员\');\r\n

    \r\n

    \r\n INSERT INTO TestTitle VALUES (\'张三\', \'系统管理员\');\r\n

    \r\n

    \r\n INSERT INTO TestTitle VALUES (\'张三\', \'网络管理员\');\r\n

    \r\n

    \r\n INSERT INTO TestTitle VALUES (\'李四\', \'项目经理\');\r\n

    \r\n

    \r\n INSERT INTO TestTitle VALUES (\'李四\', \'系统分析员\');\r\n

    \r\n

    \r\n
    \r\n

    \r\n

    \r\n 要求\r\n

    \r\n

    \r\n 对于测试数据,要求查询结果为:\r\n

    \r\n

    \r\n 张三程序员,系统管理员,网络管理员\r\n

    \r\n

    \r\n 李四项目经理,系统分析员\r\n

    \r\n

    \r\n 这种结构的结果。\r\n

    \r\n

    \r\n 思路\r\n

    \r\n

    \r\n 简单查看这个结果,很像对字符型的GROUP BY处理。\r\n

    \r\n

    \r\n 数值类型的可以SUM,但是字符类型的无法这么处理。\r\n

    \r\n

    \r\n 只好依次MAX(1) + MAX(2) + MAX(3)这种办法来处理。\r\n

    \r\n

    \r\n 实现\r\n

    \r\n

    \r\n 第一步,设置好分组的编号\r\n

    \r\n

    \r\n SELECT\r\n

    \r\n

    \r\n ROW_NUMBER() OVER(PARTITION BY name ORDER BY title) AS no,\r\n

    \r\n

    \r\n name,\r\n

    \r\n

    \r\n title\r\n

    \r\n

    \r\n FROM\r\n

    \r\n

    \r\n TestTitle\r\n

    \r\n

    \r\n ORDER BY\r\n

    \r\n

    \r\n name,\r\n

    \r\n

    \r\n title\r\n

    \r\n

    \r\n no                   name       title\r\n

    \r\n

    \r\n -------------------- ---------- ----------\r\n

    \r\n

    \r\n                    1李四        系统分析员\r\n

    \r\n

    \r\n                    2李四        项目经理\r\n

    \r\n

    \r\n                    1张三        程序员\r\n

    \r\n

    \r\n                    2张三        网络管理员\r\n

    \r\n

    \r\n                    3张三        系统管理员\r\n

    \r\n

    \r\n 第二步,根据有编号的子查询,进行分组处理\r\n

    \r\n

    \r\n SELECT\r\n

    \r\n

    \r\n name,\r\n

    \r\n

    \r\n CASE WHEN COUNT(title) = 1 THEN MAX(title)\r\n

    \r\n

    \r\n        WHEN COUNT(title) = 2 THEN\r\n

    \r\n

    \r\n          MAX( CASE WHEN SubQuery.no = 1 THEN title + \',\' ELSE \'\' END )\r\n

    \r\n

    \r\n          + MAX( CASE WHEN SubQuery.no = 2 THEN titleELSE \'\' END )\r\n

    \r\n

    \r\n        WHEN COUNT(title) = 3 THEN\r\n

    \r\n

    \r\n          MAX( CASE WHEN SubQuery.no = 1 THEN title + \',\' ELSE \'\' END )\r\n

    \r\n

    \r\n          + MAX( CASE WHEN SubQuery.no = 2 THEN title + \',\'ELSE \'\' END )\r\n

    \r\n

    \r\n          + MAX( CASE WHEN SubQuery.no = 3 THEN titleELSE \'\' END )\r\n

    \r\n

    \r\n END AS new_title\r\n

    \r\n

    \r\n FROM\r\n

    \r\n

    \r\n (\r\n

    \r\n

    \r\n SELECT\r\n

    \r\n

    \r\n     ROW_NUMBER() OVER(PARTITION BY name ORDER BY title) AS no,\r\n

    \r\n

    \r\n     name,\r\n

    \r\n

    \r\n     title\r\n

    \r\n

    \r\n FROM\r\n

    \r\n

    \r\n     TestTitle\r\n

    \r\n

    \r\n ) subQuery\r\n

    \r\n

    \r\n GROUP BY\r\n

    \r\n

    \r\n name\r\n

    \r\n

    \r\n 执行结果\r\n

    \r\n

    \r\n name       new_title\r\n

    \r\n

    \r\n ---------- ----------------------------------\r\n

    \r\n

    \r\n 李四        系统分析员,项目经理\r\n

    \r\n

    \r\n 张三        程序员,网络管理员,系统管理员\r\n

    \r\n

    \r\n
    \r\n

    \r\n

    \r\n
    \r\n

    \r\n

    \r\n
    \r\n

    \r\n

    \r\n 对于SQL Server 2005 以上版本使用FOR XML的方式测试表与测试数据要求\r\n

    \r\n

    \r\n 与前面的一样\r\n

    \r\n

    \r\n 思路\r\n

    \r\n

    \r\n 首先把一个用户的数据,单独的读取出来\r\n

    \r\n

    \r\n 然后按照分组进行处理\r\n

    \r\n

    \r\n 实现\r\n

    \r\n

    \r\n 第一步 把一个用户的数据,单独的读取出来\r\n

    \r\n

    \r\n SELECT\r\n

    \r\n

    \r\n \',\' + title\r\n

    \r\n

    \r\n FROM\r\n

    \r\n

    \r\n TestTitle\r\n

    \r\n

    \r\n WHERE\r\n

    \r\n

    \r\n name = \'张三\'\r\n

    \r\n

    \r\n FOR XML PATH(\'\')\r\n

    \r\n

    \r\n 第二步Group By每个人\r\n

    \r\n

    \r\n SELECT\r\n

    \r\n

    \r\n name,\r\n

    \r\n

    \r\n STUFF(\r\n

    \r\n

    \r\n    (\r\n

    \r\n

    \r\n    SELECT\r\n

    \r\n

    \r\n      \',\' + title\r\n

    \r\n

    \r\n    FROM\r\n

    \r\n

    \r\n      TestTitle subTitle\r\n

    \r\n

    \r\n    WHERE\r\n

    \r\n

    \r\n      name = TestTitle.name\r\n

    \r\n

    \r\n    FOR XML PATH(\'\')\r\n

    \r\n

    \r\n    ),\r\n

    \r\n

    \r\n    1, 1, \'\') AS allTitle\r\n

    \r\n

    \r\n FROM\r\n

    \r\n

    \r\n TestTitle\r\n

    \r\n

    \r\n GROUP BY\r\n

    \r\n

    \r\n name\r\n

    \r\n

    \r\n 执行结果\r\n

    \r\n

    \r\n name      allTitle\r\n

    \r\n

    \r\n ---------- --------------------------------\r\n

    \r\n

    \r\n 李四        项目经理,系统分析员\r\n

    \r\n

    \r\n 张三        程序员,系统管理员,网络管理员\r\n

    \r\n

    \r\n
    \r\n

    \r\n

    \r\n  \r\n

    \r\n

    \r\n 对于SQL Server 2005 以上版本使用 CTE 的处理方式 (使用递归方式处理)\r\n

    \r\n

    \r\n  \r\n

    \r\n

    \r\n WITH
    \r\nt1  AS
    \r\n(
    \r\n  SELECT
    \r\n    ROW_NUMBER() OVER(PARTITION BY name ORDER BY title) AS ID,
    \r\n    name,
    \r\n    title
    \r\n  FROM
    \r\n    TestTitle
    \r\n),
    \r\nt2 AS
    \r\n(
    \r\n  SELECT 
    \r\n    t1.id, 
    \r\n    t1.name, 
    \r\n    CAST(t1.title AS varchar(100)) AS title
    \r\n  FROM 
    \r\n    t1 
    \r\n  WHERE 
    \r\n    t1.id = 1
    \r\n  UNION ALL
    \r\n  SELECT 
    \r\n    t1.id, 
    \r\n    t2.name, 
    \r\n    CAST( t1.title + \',\' + t2.title AS varchar(100)) AS title
    \r\n  FROM 
    \r\n    t1, t2
    \r\n  WHERE 
    \r\n    t1.name = t2.name
    \r\n    AND t1.id = (t2.id + 1)
    \r\n)
    \r\nSELECT
    \r\n  name, 
    \r\n  title
    \r\nFROM
    \r\n  t2
    \r\nWHERE
    \r\n  NOT EXISTS (
    \r\n    SELECT 1
    \r\n    FROM t2 t22
    \r\n    WHERE
    \r\n      t2.name = t22.name
    \r\n      AND t2.id < t22.id
    \r\n  );\r\n

    \r\n

    \r\n  \r\n

    \r\n

    \r\n name       title\r\n

    \r\n

    \r\n ---------- -----------------------------------------------------------
    \r\n-------------------------------
    \r\n张三         系统管理员,网络管理员,程序员\r\n

    \r\n

    \r\n 李四         项目经理,系统分析员\r\n

    \r\n

    \r\n
    \r\n(2 行受影响)\r\n

    \r\n

    \r\n  \r\n

    \r\n

    \r\n  \r\n

    \r\n

    \r\n
    \r\n

    \r\n

    \r\n 对于MySQL使用 GROUP_CONCAT 函数 的方式进行处理(非常简单)\r\n

    \r\n

    \r\n  \r\n

    \r\n

    \r\n mysql> SELECT
    \r\n    ->   name,
    \r\n    ->   GROUP_CONCAT(title) AS allTitle
    \r\n    -> FROM
    \r\n    ->   TestTitle
    \r\n    -> GROUP BY
    \r\n    ->   name;
    \r\n+------+------------------------------+
    \r\n| name | allTitle                     |
    \r\n+------+------------------------------+
    \r\n| 李四 | 项目经理,系统分析员          |
    \r\n| 张三 | 程序员,系统管理员,网络管理员 |
    \r\n+------+------------------------------+
    \r\n2 rows in set (0.00 sec)\r\n

    \r\n

    \r\n  \r\n

    \r\n

    \r\n
    \r\n

    \r\n

    \r\n  \r\n

    \r\n

    \r\n 对于Oracle使用 WMSYS.WM_CONCAT 函数 的方式进行处理(也非常简单)\r\n

    \r\n

    \r\n  \r\n

    \r\n

    \r\n SQL> 
    \r\nSQL> SELECT
    \r\n  2    name,
    \r\n  3    WMSYS.WM_CONCAT(title) AS allTitle
    \r\n  4  FROM
    \r\n  5    TestTitle
    \r\n  6  GROUP BY
    \r\n  7    name;\r\n

    \r\n

    \r\n NAME
    \r\n----------
    \r\nALLTITLE
    \r\n-------------------------------------------
    \r\n李四
    \r\n项目经理,系统分析员\r\n

    \r\n

    \r\n 张三
    \r\n程序员,系统管理员,网络管理员\r\n

    \r\n

    \r\n
    \r\n

    \r\n

    \r\n
    \r\n

    \r\n

    \r\n
    \r\n

    \r\n

    \r\n
    \r\n \r\n

    \r\n

    \r\n 对于 PostgreSQL 使用 string_agg  函数 的方式进行处理(也非常简单)\r\n

    \r\n

    \r\n  \r\n

    \r\n

    \r\n
    \r\n

    \r\n

    \r\n Test=#\r\n

    \r\n

    \r\n Test=# SELECT\r\n

    \r\n

    \r\n Test-#   name,\r\n

    \r\n

    \r\n Test-#   string_agg(title,\',\') AS allTitle\r\n

    \r\n

    \r\n Test-# FROM\r\n

    \r\n

    \r\n Test-#   TestTitle\r\n

    \r\n

    \r\n Test-# GROUP BY\r\n

    \r\n

    \r\n Test-#   name;\r\n

    \r\n

    \r\n  name |           alltitle\r\n

    \r\n

    \r\n ------+------------------------------\r\n

    \r\n

    \r\n  李四 | 项目经理,系统分析员\r\n

    \r\n

    \r\n  张三 | 程序员,系统管理员,网络管理员\r\n

    \r\n

    \r\n (2 行记录)\r\n

    \r\n

    \r\n
    \r\n

    \r\n

    \r\n
    \r\n

    \r\n

    \r\n
    \r\n

    \r\n

    \r\n
    \r\n

    \r\n

    \r\n 对于 DB2 ,也是使用 CTE 递归的方式处理\r\n

    \r\n

    \r\n
    \r\nWITH
    \r\nt1 (id, name, title) AS
    \r\n(
    \r\n  SELECT
    \r\n    ROW_NUMBER() OVER(PARTITION BY name ORDER BY title) AS ID,
    \r\n    name,
    \r\n    title
    \r\n  FROM
    \r\n    TestTitle
    \r\n),
    \r\nt2 (id, name, title) AS
    \r\n(
    \r\n  SELECT 
    \r\n    t1.id, 
    \r\n    t1.name, 
    \r\n    CAST(t1.title AS varchar(100)) AS title
    \r\n  FROM 
    \r\n    t1 
    \r\n  WHERE 
    \r\n    t1.id = 1
    \r\n  UNION ALL
    \r\n  SELECT 
    \r\n    t1.id, 
    \r\n    t2.name, 
    \r\n    CAST( t1.title || \',\' || t2.title AS varchar(100)) AS title
    \r\n  FROM 
    \r\n    t1, t2
    \r\n  WHERE 
    \r\n    t1.name = t2.name
    \r\n    AND t1.id = (t2.id + 1)
    \r\n)
    \r\nSELECT
    \r\n  name, 
    \r\n  title
    \r\nFROM
    \r\n  t2
    \r\nWHERE
    \r\n  NOT EXISTS (
    \r\n    SELECT 1
    \r\n    FROM t2 t22
    \r\n    WHERE
    \r\n      t2.name = t22.name
    \r\n      AND t2.id < t22.id
    \r\n  );\r\n

    \r\n

    \r\n  \r\n

    \r\n

    \r\n NAME       TITLE\r\n

    \r\n

    \r\n ---------- ---------------------------------------------------------------------
    \r\n-------------------------------
    \r\nSQL0347W  递归公共表表达式 \"WZQ.T2\" 可能包含无限循环。  SQLSTATE=01605\r\n

    \r\n

    \r\n 李四       项目经理,系统分析员\r\n

    \r\n

    \r\n 张三       网络管理员,系统管理员,程序员\r\n

    \r\n

    \r\n
    \r\n  已选择 2 条记录,打印 1 条警告消息。\r\n

    \r\n

    \r\n
    \r\n

    \r\n

    \r\n
    \r\n

    \r\n

    \r\n
    \r\n

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6514, 'test', '20151206000236', '2015-01-04 14:47:57', '2019-03-25 21:29:22', '

    \r\n easyui datagrid 过滤用 combotree的时候 绑定动态数据用 url属性 直接写用data属性\r\n

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6515, '201513104233108', '201513104233108', '2015-01-04 15:31:18', '2019-03-25 21:29:22', '测试001', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6516, 'csharp-winform-infinitus-using-recursion-combobox-classification', 'WinForm学习笔记010:C#中Winform利用递归将Combobox实现无限极分类', '2015-01-04 15:55:44', '2019-03-26 00:11:48', '

    \r\n 递归思路
    \r\n

    \r\n

    \r\n 实现如下
    \r\n

    \r\n

    \r\n  \r\n

    \r\n
    \r\n

    \r\n   #region 加载分类列表\r\n

    \r\n

    \r\n \r\n

    \r\n

    \r\n         //加载分类列表\r\n

    \r\n

    \r\n         private void InitCategory()\r\n

    \r\n

    \r\n         {\r\n

    \r\n

    \r\n             //MessageBox.Show(\"开始加载分类...\");\r\n

    \r\n

    \r\n             //cmbCategory.DisplayMember=\r\n

    \r\n

    \r\n             CategoryResult category = TerwerHelper.GetCategories();\r\n

    \r\n

    \r\n             // 从数据库中获取菜单列表\r\n

    \r\n

    \r\n             List<Category> lst = category.categories;\r\n

    \r\n

    \r\n             // 递归分组,实现树形效果\r\n

    \r\n

    \r\n             var groupedMenuList = GroupMenuList(lst, 0, 0);\r\n

    \r\n

    \r\n             cmbCategory.DataSource = groupedMenuList;\r\n

    \r\n

    \r\n             cmbCategory.SelectedIndex = 0;\r\n

    \r\n

    \r\n             cmbCategory.DisplayMember = \"title\";\r\n

    \r\n

    \r\n             cmbCategory.ValueMember = \"id\";\r\n

    \r\n

    \r\n             //MessageBox.Show(\"分类加载完毕!\");\r\n

    \r\n

    \r\n         }\r\n

    \r\n

    \r\n \r\n

    \r\n

    \r\n         private List<Category> GroupMenuList(List<Category> menuList, int parentId, int level)\r\n

    \r\n

    \r\n         {\r\n

    \r\n

    \r\n             var childMenuList = menuList.Where(a => a.parent == parentId).ToList();\r\n

    \r\n

    \r\n             List<Category> groupedList = new List<Category>();\r\n

    \r\n

    \r\n             foreach (var it in childMenuList)\r\n

    \r\n

    \r\n             {\r\n

    \r\n

    \r\n                 //groupedList.Add(new Category() {id = it.id, title = new string(\'.\', level*3) + it.title});\r\n

    \r\n

    \r\n                 groupedList.Add(new Category() {id = it.id, title = new string(\' \', level*3) + \"|--\" + it.title});\r\n

    \r\n

    \r\n                 groupedList.AddRange(GroupMenuList(menuList, it.id, level + 1));\r\n

    \r\n

    \r\n             }\r\n

    \r\n

    \r\n             return groupedList;\r\n

    \r\n

    \r\n         }\r\n

    \r\n

    \r\n \r\n

    \r\n

    \r\n         #endregion\r\n

    \r\n
    \r\n

    \r\n  \r\n

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6519, '201515805235852', '201515805235852', '2015-01-05 05:02:02', '2019-03-25 21:29:22', '测', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6523, 'oracle-install-virtualbox-linux6-database-11g-system-review', 'Oracle VirtualBox安装Linux6和Oracle Database 11g', '2015-01-07 01:06:41', '2019-03-26 00:08:58', '

    \r\n Oracle VirtualBox + Linux6 + Database 11g 系统安装篇\r\n

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6526, 'winform-note-009-exit-or-exit-the-window', 'WinForm学习笔记009:退出程序还是退出窗口', '2015-01-07 01:27:34', '2019-03-25 21:29:22', '

    \r\n /*当本窗口是主线程窗口,以下三种方法均可以退出程序\r\n

    \r\n

    \r\n *当本窗口不是主窗口时,如果要退出整个程序,应采用第3种方法,将一次性关闭程序上存在的所有线程。\r\n

    \r\n

    \r\n *如果只是想关闭当前窗口而不退出程序,应采用第一种方法\r\n

    \r\n

    \r\n *当本窗口不是主窗口时,采用第2种方法退出程序时,将会再执行关闭主窗体的步骤。\r\n

    \r\n

    \r\n */\r\n

    \r\n

    \r\n this.Close();\r\n

    \r\n

    \r\n Application.Exit();\r\n

    \r\n

    \r\n Application.ExitThread(); \r\n

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6533, 'simple-tooltip-winform-study-notes-009-csharp-winform-usage', 'WinForm学习笔记011:C#Winform中ToolTip的简单用法', '2015-01-07 01:39:42', '2019-03-25 21:29:22', '

    \r\n  知识准备\r\n

    \r\n

    \r\n ToolTip信息提示框的作用就不用说了吧,我也没去细研究,只是学习了一下怎么去用,简单记录一下:\r\n

    \r\n

    \r\n C#中提供了信息提示框,这有很多用处,可以提示控件或者用户自定义的属性信息,而且可以自动弹出或者用户指定弹出,也可以动画效果弹出。\r\n

    \r\n

    \r\n 使用方法:
    \r\n①鼠标移动到控件或指定的位置自动显示:ToolTip.SetToolTip 方法 ,注意相关参数的设置。
    \r\n②动画效果:参数:AutoPopDelay InitialDelay ReshowDelay
    \r\n例如:\r\n

    \r\n
    \r\n
    \r\n
    \r\n \r\n \r\n \r\n \r\n \r\n \r\n
    \r\n
    \r\n
    \r\n // Create the ToolTip and associate with the Form container.\r\n
    \r\n
    \r\n ToolTip toolTip1 =new ToolTip();\r\n
    \r\n
    \r\n  \r\n
    \r\n
    \r\n // Set up the delays for the ToolTip.\r\n
    \r\n
    \r\n toolTip1.AutoPopDelay = 5000;\r\n
    \r\n
    \r\n toolTip1.InitialDelay = 1000;\r\n
    \r\n
    \r\n toolTip1.ReshowDelay = 500;\r\n
    \r\n
    \r\n // Force the ToolTip text to be displayed whether or not the form is active.\r\n
    \r\n
    \r\n toolTip1.ShowAlways =true;\r\n
    \r\n
    \r\n     \r\n
    \r\n
    \r\n // Set up the ToolTip text for the Button and Checkbox.\r\n
    \r\n
    \r\n toolTip1.SetToolTip(this.button1,\"My button1\");\r\n
    \r\n
    \r\n toolTip1.SetToolTip(this.checkBox1,\"My checkBox1\");\r\n
    \r\n

    \r\n
    \r\n

    \r\n

    \r\n
    \r\n

    \r\n

    \r\n
    \r\n

    \r\n
    \r\n
    \r\n
    \r\n

    \r\n
    \r\n

    \r\n

    \r\n
    \r\n

    \r\n

    \r\n
    \r\n

    \r\n
    \r\n
    \r\n

    \r\n ③提示图片设置:
    \r\nToolTipIcon属性
    \r\nError 错误图标 
    \r\nInfo 信息图标。 
    \r\nNone 不是标准图标。 
    \r\nWarning 警告图标。 
    \r\n④气泡样式:ToolTip.IsBalloon 属性 设置为True
    \r\n⑤自定义位置和触发事件显示:ToolTip.Show 方法,注意相关参数的设置。
    \r\n例如:\r\n

    \r\n
    \r\n
    \r\n \r\n \r\n \r\n \r\n \r\n \r\n
    \r\n
    \r\n
    \r\n m_ToolTip.Show(pStringBuilder.ToString(),\r\n
    \r\n
    \r\n m_HookHelperJP.FormObjects.Win32Window,e.x + r.Left, e.y + r.Top);\r\n
    \r\n

    \r\n
    \r\n

    \r\n

    \r\n
    \r\n

    \r\n

    \r\n
    \r\n

    \r\n
    \r\n
    \r\n
    \r\n \r\n
    \r\n
    \r\n

    \r\n 使用技巧\r\n

    \r\n

    \r\n
    \r\n①ToolTip.Show时显示不能隐藏问题
    \r\n可做以下处理:在再次触发Show前进行Hide操作
    \r\n②m_ToolTip信息不能及时更新问题
    \r\n这是因为其内存清理存在问题,处理方法:在显示前清楚内存,重新实例化。
    \r\n例如:\r\n

    \r\n
    \r\n
    \r\n
    \r\n \r\n \r\n \r\n \r\n \r\n \r\n
    \r\n
    \r\n
    \r\n m_ToolTip.Dispose();\r\n
    \r\n
    \r\n m_ToolTip =new ToolTip();\r\n
    \r\n
    \r\n m_ToolTip.ToolTipIcon = ToolTipIcon.Info;\r\n
    \r\n
    \r\n //m_ToolTip.IsBalloon = true;\r\n
    \r\n
    \r\n m_ToolTip.ShowAlways =true;\r\n
    \r\n
    \r\n m_ToolTip.ToolTipTitle = sName;\r\n
    \r\n
    \r\n m_ToolTip.Show(pStringBuilder.ToString(),\r\n
    \r\n
    \r\n m_HookHelperJP.FormObjects.Win32Window, e.x + r.Left, e.y + r.Top);\r\n
    \r\n

    \r\n
    \r\n

    \r\n

    \r\n
    \r\n

    \r\n

    \r\n
    \r\n

    \r\n
    \r\n
    \r\n
    \r\n

    \r\n
    \r\n

    \r\n

    \r\n
    \r\n

    \r\n

    \r\n
    \r\n

    \r\n
    \r\n
    \r\n

    \r\n ③固定宽度设置
    \r\nToolTip没有直接提供Width属性,找了很久可用以下方法设置:
    \r\n在显示前ToolTip.Popup 事件 中通过参数PopupEventArgs.Size进行设置。但是这只能覆盖多出的信息。这种处理不合理。
    \r\n建议另外一种方法:设置每一行固定字符,多出的则换行显示\r\n

    \r\n\"\"', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6541, 'net-core-5-learn-note-001-embracing-the-open-source-era', '.NET Core 5学习笔记001:拥抱开源时代', '2015-01-08 05:52:20', '2019-03-26 00:08:38', '

    \r\n 2014年,对.NET来说终究是不平凡的一年,因为.NET开源了。笔者从.NET2.0、3.5、4.0、4.5的时候,想查看源代码还得要反编译工具,这对于了解原理很不方便。现在终于可以完全掌控手中的.NET代码了,笔者将用一个系列一步步从源码深层剖析,解开.NET开源面纱。\r\n

    \r\n

    \r\n Welcome to the .NET Foundation(欢迎来到.NET基金会)\r\n

    \r\n

    \r\n 11/12/2014 NEWS: Announcing new governance model and project contributions to the .NET Foundation\r\n

    \r\n

    \r\n The .NET Foundation is an independent organization to foster open development and collaboration around the growing collection of open source technologies for .NET, Microsoft’s comprehensive development framework. It serves as a forum for commercial and community developers alike to strengthen the future of the .NET ecosystem by promoting openness, community participation and rapid innovation.\r\n

    \r\n

    \r\n Community engagement through open source foundations has been proven to nurture and advance core technologies that the IT industry relies upon. We found that there was enough momentum around open source .NET to create a separate independent foundation. Developers everywhere are innovating rapidly with the power and flexibility of .NET, and the growing community is in need of a developer forum, a test bed, practices and processes that will strengthen the future of the .NET ecosystem.\r\n

    \r\n

    \r\n Value for projects joining the .NET Foundation include:\r\n

    \r\n
      \r\n
    • \r\n Direct and more frequent access to .NET project teams at Microsoft and across the community\r\n
    • \r\n
    • \r\n More opportunities to make your project visible to .NET developers, and enterprises\r\n
    • \r\n
    • \r\n Increased opportunities for personal visibility and community influence\r\n
    • \r\n
    • \r\n Commercially friendly IP and copyright terms and licenses that remove barriers to foundation entry\r\n
    • \r\n
    \r\n

    \r\n Meet the key people behind the .NET Foundation. See our Blog and FAQ for more information and join the conversations on our forums.\r\n

    \r\n

    \r\n We look forward to working together!\r\n

    \r\n

    \r\n  \r\n

    \r\n

    \r\n .NET Core 5(.NET5核心库
    \r\n

    \r\n

    \r\n .NET Core 5 is the small optimized runtime that is the basis of ASP.NET Core 5. It currently runs on Windows, and will be extended to support Linux and Mac. It is a high-performance and modular design, and supports full side by side to make it easy to adopt new .NET Core versions without affecting other apps. These products are actively developed by the .NET team and in collaboration with a community of open source developers. Together we are dedicated to improving and extending the .NET platform with new features and for new scenarios.\r\n

    \r\n

    \r\n .NET Core has two major components. It includes a small runtime that is built from the same codebase as the .NET Framework CLR. The .NET Core runtime includes the same GC and JIT (RyuJIT), but doesn’t include features like Application Domains or Code Access Security. The runtime is delivered on NuGet, via the Microsoft.CoreCLR package.\r\n

    \r\n

    \r\n .NET Core also includes the base class libraries. These libraries are largely the same code as the .NET Framework class libraries, but have been factored (removal of dependencies) to enable us to ship a smaller set of libraries. These libraries are shipped as System.* NuGet packages on NuGet.org.\r\n

    \r\n

    \r\n Project Details(项目详情
    \r\n

    \r\n\r\n

    \r\n Quicklinks(快速链接
    \r\n

    \r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6551, '20150108213902', '20150108213902', '2015-01-08 13:39:01', '2019-03-25 21:29:22', '说实话,一直积累的东西只有3方面,技术,业务,思想。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6552, 'asp-net-image-upload-cases-1', 'Asp .NET多图片上传案例1', '2015-01-09 01:32:32', '2019-03-25 21:29:22', 'Asp .NET多图片上传案例', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6555, 'context-requestfiles-null-problem', 'context.Request.Files为NULL问题', '2013-01-09 06:43:03', '2019-03-25 21:29:22', '

    \r\n  \r\n

    \r\n

    \r\n 在实现图片上传功能的时候出现在ashx等处理页面出现context.Request.Files为NULL异常,有几点需要注意:\r\n

    \r\n

    \r\n 1、在客户端可以form用submit提交,如下:\r\n

    \r\n

    \r\n <%@ Page Language=\"C#\" AutoEventWireup=\"true\" CodeFile=\"Default.aspx.cs\" Inherits=\"_Default\" %>\r\n

    \r\n

    \r\n <!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">
    \r\n<html xmlns=\"http://www.w3.org/1999/xhtml\">
    \r\n<head runat=\"server\">
    \r\n    <title></title>
    \r\n    <script src=\"http://archive.cnblogs.com/a/2084139/JS/jquery-1.3.2.js\" rel=\"nofollow\"/>    <script language=\"javascript\" type=\"text/javascript\">
    \r\n        function UpLoad() {
    \r\n            $(\"#form1\").submit();            
    \r\n        } 
    \r\n        
    \r\n    </script>\r\n

    \r\n

    \r\n </head>
    \r\n<body>
    \r\n    <form id=\"form1\" method=\"post\" enctype=\"multipart/form-data\" action=\"ImageHandler.ashx\">
    \r\n    <div>
    \r\n        <input id=\"File1\" type=\"file\" runat=\"server\"/>
    \r\n        <input id=\"Button1\" type=\"button\" value=\"上传\" onclick=\"UpLoad()\" /></div> 
    \r\n        <div id=\"imgList\"></div>      
    \r\n    </form>
    \r\n</body>
    \r\n</html>\r\n

    \r\n

    \r\n 2、form表单需要加上属性method=\"post\" enctype=\"multipart/form-data\"\r\n

    \r\n

    \r\n 3、文件控件需要加上runat=\"server\"属性\r\n

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6559, 'understand-why-tcp-requires-three-way-handshake', '理解TCP为什么需要进行三次握手', '2015-01-10 08:32:05', '2019-03-26 00:11:35', '

    \r\n 原理\r\n

    \r\n

    \r\n  在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。\r\n

    \r\n

    \r\n 第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;\r\n

    \r\n

    \r\n 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器 进入SYN_RECV状态;\r\n

    \r\n

    \r\n 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入 ESTABLISHED状态,完成三次握手。\r\n

    \r\n

    \r\n 通过这样的三次握手,客户端与服务端建立起可靠的双工的连接,开始传送数据。\r\n

    \r\n

    \r\n 三次握手的最主要目的是保证连接是双工的,可靠更多的是通过重传机制来保证的。\r\n

    \r\n

    \r\n 参考\r\n

    \r\n

    \r\n 1 http://www.cnblogs.com/yuilin/archive/2012/11/05/2755298.html\r\n

    \r\n

    \r\n 2 http://www.seanyxie.com/wireshark%E6%8A%93%E5%8C%85%E5%9B%BE%E8%A7%A3-tcp%E4%B8%89%E6%AC%A1%E6%8F%A1%E6%89%8B%E5%9B%9B%E6%AC%A1%E6%8C%A5%E6%89%8B%E8%AF%A6%E8%A7%A3/\r\n

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6561, '20150111001757', '20150111001757', '2015-01-10 16:17:57', '2019-03-25 21:29:22', '用心对待工作,乐观对待生活。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6563, 'video-address-resolution-001-java-package-of-public-httphelper', 'aaa', '2015-01-11 05:55:04', '2019-03-25 21:29:22', 'bbb', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6565, '20150111142534', '20150111142534', '2015-01-11 06:25:33', '2019-03-25 21:29:22', '任何时候,都不要丧失创造力。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6569, 'spring-learning-notes-050-getting-started-with-spring-mvc-hello-worldo', 'Spring学习笔记050:Spring MVC入门:Hello World', '2015-01-11 09:12:18', '2019-03-25 21:29:22', '

    spring下载

    \r\nhttp://projects.spring.io/spring-framework/\r\n

    安装spring

    \r\n有两种方式建立项目,建议使用maven项目方式,可以更好的控制jar包依赖。\r\n

    dynamic web project方式

    \r\n在maven中作如下配置即可(关于maven请参考本站关于maven的文章)。\r\n\r\n关于dynamic web project转换为maven请参考:eclipse java工程跟maven工程的互相转换\r\n\r\n加入spring mvc的方式,直接在pom.xml里面加入以下代码即可:\r\n
    \r\n

       <!--spring -->

    \r\n

          <dependency>

    \r\n

            <groupId>org.springframework</groupId>

    \r\n

            <artifactId>spring-core</artifactId>

    \r\n

            <version>3.2.13.RELEASE</version>

    \r\n

            <type>jar</type>

    \r\n

            <scope>compile</scope>

    \r\n

          </dependency>

    \r\n

          <dependency>

    \r\n

            <groupId>org.springframework</groupId>

    \r\n

            <artifactId>spring-context</artifactId>

    \r\n

            <version>3.2.13.RELEASE</version>

    \r\n

          </dependency>

    \r\n

          <dependency>

    \r\n

            <groupId>org.springframework</groupId>

    \r\n

            <artifactId>spring-web</artifactId>

    \r\n

            <version>3.2.13.RELEASE</version>

    \r\n

            <type>jar</type>

    \r\n

            <scope>compile</scope>

    \r\n

          </dependency>

    \r\n

          <dependency>

    \r\n

            <groupId>org.springframework</groupId>

    \r\n

            <artifactId>spring-webmvc</artifactId>

    \r\n

            <version>3.2.13.RELEASE</version>

    \r\n

          </dependency>

    \r\n 
    \r\n注意加入后要更新eclipse项目。\r\n\r\n\"QQ截图20150113145555\"\r\n\r\n \r\n\r\n \r\n\r\n \r\n\r\n \r\n\r\n \r\n

    maven项目方式

    \r\n

    项目结构

    \r\n\"2015-01-15_094937\"\r\n

    配置与Hello World

    \r\n

    基于maven

    \r\n1、修改pom.xml,添加必要依赖\r\n\r\n2、添加配置文件\r\n\r\napplicationContext.xml\r\n
     \r\n

    <?xml version=\"1.0\" encoding=\"UTF-8\"?>

    \r\n

    <beans xmlns=\"http://www.springframework.org/schema/beans\"

    \r\n

       xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:context=\"http://www.springframework.org/schema/context\"

    \r\n

       xsi:schemaLocation=\"http://www.springframework.org/schema/beans

    \r\n

           http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd\">

    \r\n

    </beans>

    \r\n
    \r\nSpringMVC-servlet.xml\r\n
    \r\n
     \r\n

    <?xml version=\"1.0\" encoding=\"UTF-8\"?>

    \r\n

    <beans xmlns=\"http://www.springframework.org/schema/beans\"

    \r\n

       xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:context=\"http://www.springframework.org/schema/context\"

    \r\n

       xmlns:mvc=\"http://www.springframework.org/schema/mvc\"

    \r\n

       xsi:schemaLocation=\" 

    \r\n

            http://www.springframework.org/schema/beans

    \r\n

            http://www.springframework.org/schema/beans/spring-beans.xsd  

    \r\n

            http://www.springframework.org/schema/context

    \r\n

            http://www.springframework.org/schema/context/spring-context.xsd 

    \r\n

            http://www.springframework.org/schema/mvc 

    \r\n

            http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd\">

    \r\n

       <!-- 指定自动扫描路径 -->

    \r\n

       <context:component-scan base-package=\"com.terwer.player.action\"></context:component-scan>

    \r\n

       <!-- 视图解析器,使用jstl -->

    \r\n

       <bean id=\"viewResolver\"

    \r\n

          class=\"org.springframework.web.servlet.view.UrlBasedViewResolver\">

    \r\n

          <property name=\"viewClass\"

    \r\n

            value=\"org.springframework.web.servlet.view.JstlView\" />

    \r\n

          <property name=\"prefix\" value=\"/WEB-INF/views/\" />

    \r\n

          <property name=\"suffix\" value=\".jsp\" />

    \r\n

       </bean>

    \r\n

    </beans>

    \r\n
    \r\n
    \r\nweb.xml\r\n
     \r\n

    <!DOCTYPE web-app PUBLIC

    \r\n

     \"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN\"

    \r\n

     \"http://java.sun.com/dtd/web-app_2_3.dtd\" >

    \r\n

    <web-app>

    \r\n

       <display-name>Archetype Created Web Application</display-name>

    \r\n

       <!--spring 监听器 -->

    \r\n

       <listener>

    \r\n

       <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

    \r\n

       </listener>

    \r\n

       <!--spring MVC拦截器 -->

    \r\n

       <servlet>

    \r\n

          <servlet-name>springMvc</servlet-name>

    \r\n

       <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

    \r\n

          <init-param>

    \r\n

            <param-name>contextConfigLocation</param-name>

    \r\n

            <param-value>/WEB-INF/SpringMVC-servlet.xml</param-value>

    \r\n

          </init-param>

    \r\n

          <load-on-startup>1</load-on-startup>

    \r\n

       </servlet>

    \r\n

       <servlet-mapping>

    \r\n

          <servlet-name>springMvc</servlet-name>

    \r\n

          <url-pattern>/</url-pattern>

    \r\n

       </servlet-mapping>

    \r\n

    </web-app>

    \r\n
    \r\n

    3、在WEB-INF/views添加页面index.jsp

    \r\n\"QQ截图20150115100250\"\r\n

    传统方式

    \r\n参考maven方式\r\n

    运行

    \r\n

    在浏览器输入

    \r\nhttp://localhost:8080/player/home/index\r\n

    效果

    \r\n\"QQ截图20150115100702\"\r\n

    全部源码下载

    \r\n\"Github\r\n

    系列导航

    \r\n

    http://www.terwer.com/special.html#用Java实现视频地址解析

    \r\n

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6574, 'another-use-of-ueditor', 'Ueditor的另外一种用法', '2014-01-12 02:22:41', '2019-03-25 21:29:22', '

    \r\n 页面\r\n

    \r\n

    \r\n ueditor相关引用\r\n

    \r\n

    \r\n  \r\n

    \r\n

    \r\n          <!--ueditor start-->\r\n

    \r\n

    \r\n          <script type=\"text/javascript\">\r\n

    \r\n

    \r\n              window.UEDITOR_HOME_URL = \"/ueditor/\";\r\n

    \r\n

    \r\n          </script>\r\n

    \r\n

    \r\n          <script type=\"text/javascript\" src=\"../ueditor/editor_config.js\"></script>\r\n

    \r\n

    \r\n          <script type=\"text/javascript\" src=\"../ueditor/editor_all.js\"></script>\r\n

    \r\n

    \r\n          <link rel=\"stylesheet\" href=\"../ueditor/themes/default/ueditor.css\" />\r\n

    \r\n

    \r\n          <!--ueditor end-->\r\n

    \r\n

    \r\n <!--page start-->\r\n

    \r\n

    \r\n <asp:Label ID=\"ediZtdDesc\" runat=\"server\" Visible=\"false\" Text=\"\"></asp:Label>\r\n

    \r\n

    \r\n     <script type=\"text/plain\" id=\"editorZtdDesc\"><%=this.ediZtdDesc.Text%></script>\r\n

    \r\n

    \r\n     <script type=\"text/javascript\">\r\n

    \r\n

    \r\n         $(document).ready(function() {\r\n

    \r\n

    \r\n             var editorZtdDesc = new UE.ui.Editor({\r\n

    \r\n

    \r\n             imageRealPath: \"/upload/ztddetayue/\",\r\n

    \r\n

    \r\n             textarea: \'ztdDesc\'\r\n

    \r\n

    \r\n         });\r\n

    \r\n

    \r\n         editorZtdDesc.render(\'editorZtdDesc\');\r\n

    \r\n

    \r\n         });\r\n

    \r\n

    \r\n      </script>\r\n

    \r\n

    \r\n <!--page end-->\r\n

    \r\n

    \r\n <--submit start-->\r\n

    \r\n

    \r\n   $(\"#Form1\").submit(function() {\r\n

    \r\n

    \r\n                  try {\r\n

    \r\n

    \r\n                      UE.getEditor(\'editorZtdDesc\').sync();\r\n

    \r\n

    \r\n                      alert($(\"#editorZtdDesc\").html());\r\n

    \r\n

    \r\n                  }\r\n

    \r\n

    \r\n                  catch (e) {\r\n

    \r\n

    \r\n                      alert(e.name  +   \" :  \"   +  e.message);\r\n

    \r\n

    \r\n                  }\r\n

    \r\n

    \r\n                  });\r\n

    \r\n\r\n

    \r\n <!--submit end-->\r\n

    \r\n

    \r\n 还要加上\r\n

    \r\n

    \r\n  \r\n

    \r\n

    \r\n 后台\r\n

    \r\n

    \r\n 提交\r\n

    \r\n

    \r\n  \r\n

    \r\n

    \r\n    string ztdDesc = Utils.ReqStrParams(\"ztdDesc\", \"\");\r\n

    \r\n

    \r\n             model.ZtdDesc = ztdDesc;\r\n

    \r\n

    \r\n             Response.Write(model.ZtdDesc);\r\n

    \r\n\r\n

    \r\n 赋值\r\n

    \r\n

    \r\n ediAfterService.Text = product.AfterService;\r\n

    \r\n

    \r\n ueditor下载\r\n

    \r\n

    \r\n 未完待续\r\n

    \r\n

    \r\n  \r\n

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6579, 'jquery-validate-length-method', 'JQuery validate扩展长度方法', '2015-01-12 06:51:59', '2019-03-25 21:29:22', '

    \r\n $.validator.methods.strlen = function(value, element, param) {\r\n

    \r\n

    \r\n                  var str = $(element).val();\r\n

    \r\n

    \r\n                  var len = 0;\r\n

    \r\n

    \r\n                  for (var i = 0; i < str.length; i++) {\r\n

    \r\n

    \r\n                      if (str.charCodeAt(i) > 255) {\r\n

    \r\n

    \r\n                          len += 2;\r\n

    \r\n

    \r\n                      }\r\n

    \r\n

    \r\n                      else {\r\n

    \r\n

    \r\n                          len += 1;\r\n

    \r\n

    \r\n                      }\r\n

    \r\n

    \r\n                  }\r\n

    \r\n

    \r\n                  return (len - param) <= 0;\r\n

    \r\n

    \r\n              }\r\n

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6581, 'eclipse-settings-for-auto-completion', 'eclipse自动补全的设置', '2014-01-13 05:26:46', '2019-03-25 21:29:22', '

    \r\n 如果你用过Visual Studio的自动补全功能后,再来用eclipse的自动补全功能,相信大家会有些许失望。\r\n

    \r\n

    \r\n 但是eclipse其实是非常强大的,eclipse的自动补全没有VS那么好是因为eclipse的补全功能用的是默认设置。你只需要稍微修改一下就行了。\r\n

    \r\n

    \r\n 最简单的修改方式是:Windows——>Preferences——>Java-->Editor-->Content Asist,在Auto activation triggers for Java后面的文本框里只有一个“.”。现在你将其改为:\r\n

    \r\n
    \r\n

    \r\n .abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n

    \r\n
    \r\n

    \r\n 即可。然后你再试试,会发现,现在的补全功能跟VS差不多了。你还可以在Advanced和Favorite里进行 高级的设置。使用愉快,如果大\r\n

    \r\n

    \r\n
    \r\n

    \r\n

    \r\n \"\"家还有其他eclipse使用上的优化或者有意思的设置或者插件,请分享~~\r\n

    \r\n

    \r\n eclipse的一些其他玩法请参考:http://rongmayisheng.com/cat/软件和工具\r\n

    \r\n

    \r\n
    \r\n

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6589, 'eclipse-java-project-with-maven-project-to-convert', 'aaa', '2015-01-13 06:36:23', '2019-03-25 21:29:22', 'bbb', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6602, 'two-points-based-on-the-latitude-and-longitude-distance-calculations', '根据两点经纬度计算距离', '2015-01-13 08:53:39', '2019-03-26 00:08:13', '需求背景\r\n========\r\n在实际应用当中,一般是通过一个个体的编码来查找该编码对应的地区中心的经纬度,然后再根据这些经纬度来计算彼此的距离,从而估算出某些群体之间的大致距离范围(比如酒店旅客的分布范围-各个旅客的邮政编码对应的经纬度和酒店的经纬度所计算的距离范围-等等)。\r\n\r\n用GPS测出两个点的经纬度后,如何计算这两个点之间的距离呢?\r\n\r\n![](http://bcs.duapp.com/terwer/blog/2015/01/acr-length.jpg)\r\n\r\n设两点A、B的经、纬度分别为(jA,wA)(jB,wB),则半径为R的球面上两点间的最短距离(大圆弧)为:\r\n\r\n弧AB=R*arccos[sin(wA)sin(wB) cos(wA)cos(wB)*cos(jA-jB)]\r\n\r\n地球是一个近乎标准的椭球体,它的赤道半径为6378.140千米,极半径为6356.755千米,平均半径6371.004千米。如果我们假设地球是一个完美的球体,那么它的半径就是地球的平均半径,记为R。如果以0度经线为基准,那么根据地球表面任意两点的经纬度就可以计算出这两点间的地表距离(这里忽略地球表面地形对计算带来的误差,仅仅是理论上的估算值)。设第一点A的经纬度为(LonA, LatA),第二点B的经纬度为(LonB, LatB),按照0度经线的基准,东经取经度的正值(Longitude),西经取经度负值(-Longitude),北纬取90-纬度值(90-Latitude),南纬取90 纬度值(90 Latitude),则经过上述处理过后的两点被计为(MLonA, MLatA)和(MLonB, MLatB)。那么根据三角推导,可以得到计算两点距离的如下公式:\r\n\r\nC = sin(MLatA)*sin(MLatB)*cos(MLonA-MLonB) cos(MLatA)*cos(MLatB)\r\n\r\nDistance = R*Arccos(C)*Pi/180\r\n\r\n这里,R和Distance单位是相同,如果是采用6371.004千米作为半径,那么Distance就是千米为单位。\r\n\r\n如果仅对经度作正负的处理,而不对纬度作90-Latitude(假设都是北半球,南半球只有澳洲具有应用意义)的处理,那么公式将是:\r\n\r\nC = sin(LatA)*sin(LatB) cos(LatA)*cos(LatB)*cos(MLonA-MLonB)\r\n\r\nDistance = R*Arccos(C)*Pi/180\r\n\r\n以上通过简单的三角变换就可以推出。\r\n\r\n如果三角函数的输入和输出都采用弧度值,那么公式还可以写作:\r\n\r\nC = sin(LatA*Pi/180)*sin(LatB*Pi/180) cos(LatA*Pi/180)*cos(LatB*Pi/180)*cos((MLonA-MLonB)*Pi/180)\r\n\r\nDistance = R*Arccos(C)*Pi/180\r\n\r\n源码\r\n\r\n \r\n\r\n\r\n\r\n        /// \r\n\r\n        /// 地球半径 \r\n\r\n        /// \r\n\r\n        private const double EARTH_RADIUS = 6378.137;\r\n\r\n\r\n\r\n        /// \r\n\r\n        /// 根据距离算出弧度\r\n\r\n        /// \r\n\r\n        /// 距离\r\n\r\n        /// 弧长\r\n\r\n        private static double Rad(double d)\r\n\r\n        {\r\n\r\n            return d*Math.PI/180.0;\r\n\r\n        }\r\n\r\n\r\n\r\n        /// \r\n\r\n        /// 根据两点间经纬度坐标(double值),计算两点间距离,单位为米 \r\n\r\n        /// \r\n\r\n        /// 纬度1\r\n\r\n        /// 经度1\r\n\r\n        /// 经度2\r\n\r\n        /// 纬度2\r\n\r\n        /// 两点之间的距离\r\n\r\n        public static double GetDistance(double lat1, double lng1, double lat2, double lng2)\r\n\r\n        {\r\n\r\n            double radLat1 = Rad(lat1);\r\n\r\n            double radLat2 = Rad(lat2);\r\n\r\n            double a = radLat1 – radLat2;\r\n\r\n            double b = Rad(lng1) – Rad(lng2);\r\n\r\n            double s = 2*Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(a/2), 2) Math.Cos(radLat1)*Math.Cos(radLat2)*Math.Pow(Math.Sin(b/2), 2)));\r\n\r\n            s = s*EARTH_RADIUS;\r\n\r\n            s = Math.Round(s*10000)/10000;\r\n\r\n                  s=s*1000;\r\n\r\n            return s;\r\n\r\n        }\r\n\r\n\r\n\r\n\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6611, 'spring-study-notes-051-json-data-format-of-input-and-output', 'Spring学习笔记051:Spring MVC中json数据格式的输入和输出', '2015-01-14 05:32:38', '2019-03-25 21:29:22', '

    \r\n 未完待续\r\n

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6614, 'aaa', 'aaa', '2015-01-14 15:04:12', '2019-03-25 21:29:22', '未完待续', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6659, 'csharp-net-export-excel', 'C# .NET 导出Excel的另一种方法', '2015-01-15 10:56:58', '2019-03-25 21:29:22', '

    \r\n  之前的方法请参考\r\n

    \r\n

    \r\n http://www.terwer.com/mysls-output-sls-settings.html\r\n

    \r\n

    \r\n 更好的方法\r\n

    \r\n

    \r\n   protected void bt_Export_Click(object sender, System.EventArgs e)
    \r\n        {
    \r\n            string dateTimeFrom = txtDateTimeFrom.Value;
    \r\n            string dateTimeTo = txtDateTimeTo.Value;
    \r\n            string supplierID = ddlSupplier.SelectedValue;
    \r\n            DataTable dt = OrderDB.SearchOrderSupplierStatistical(dateTimeFrom, dateTimeTo, supplierID);
    \r\n            string fileName = \"SupplierStatistical-\" + DateTime.Now.ToString(\"yyyyMMddHHmmss\");
    \r\n            CreateXls(dt, fileName);
    \r\n        }\r\n

    \r\n

    \r\n         public void CreateXls(System.Data.DataTable dtData, string FileName)
    \r\n        {
    \r\n            ExcelBook eb = new ExcelBook(dtData, FileName);
    \r\n            ExcelColumnCollection ec = new ExcelColumnCollection();
    \r\n            ec.Add(new ExcelColumn(\"商家名称\"));
    \r\n            ec.Add(new ExcelColumn(\"浏览量\"));
    \r\n            ec.Add(new ExcelColumn(\"销售量\"));
    \r\n            ec.Add(new ExcelColumn(\"销售额\"));
    \r\n            eb.AddColumnNamesCollection(ec);
    \r\n            eb.IsAutoFitWidth = true;//自定适用列宽           
    \r\n            eb.WriteExcelToClient(FileName);//下载Excel文件
    \r\n        }\r\n

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6662, 'use-and-configuration-of-log4j', 'Log4j的使用与配置', '2015-01-16 09:05:13', '2019-03-25 21:29:22', '

    \r\n 安装log4j\r\n

    \r\n

    \r\n 新建maven项目,输入以下依赖\r\n

    \r\n
    \r\n

    \r\n   \r\n

    \r\n

    \r\n    <!-- log4j -->\r\n

    \r\n

    \r\n       <dependency>\r\n

    \r\n

    \r\n         <groupId>log4j</groupId>\r\n

    \r\n

    \r\n         <artifactId>log4j</artifactId>\r\n

    \r\n

    \r\n         <version>1.2.17</version>\r\n

    \r\n

    \r\n       </dependency>\r\n

    \r\n
    \r\n

    \r\n 封装LogHelper\r\n

    \r\n

    \r\n  \r\n

    \r\n

    \r\n 配置log4j.properties\r\n

    \r\n

    \r\n zhuy \r\n

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6669, 'talking-about-the-viewport-of-the-html5-tag', '浅谈HTML5之viewport标签', '2015-01-17 03:28:19', '2019-03-25 21:29:22', '

    \r\n 开发移动端网页常会在头部计入 viewport 的meta标签,这玩意儿到底有什么用呢?让我带你认识一下。\r\n

    \r\n

    \r\n 我们先来看一个例子:\r\n

    \r\n

    \r\n 在用HTML5开发手机应用或手机网页时,做好的页面不加meta viewport的话,浏览效果如下。\r\n

    \r\n

    \r\n \"1\"\r\n

    \r\n

    \r\n (无meta viewport属性)\r\n

    \r\n

    \r\n \"2\"\r\n

    \r\n

    \r\n (添加meta viewport属性)\r\n

    \r\n

    \r\n viewport的一般写法是这样的:\r\n

    \r\n
    \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
    \r\n
    \r\n
    \r\n
    \r\n
    <meta name=\"viewport\" content=\"width=device-width,height=device-height,inital-scale=1.0,maximum-scale=1.0,user-scalable=no;\" />
    \r\n
    \r\n
    \r\n

    \r\n 上面这段代码的解释\r\n

    \r\n

    \r\n 手机浏览器是把页面放在一个虚拟的“窗口”(viewport)中,通常这个虚拟的“窗口”(viewport)比屏幕宽,这样就不用把每个网页挤到很小的窗口中(这样会破坏没有针对手机浏览器优化的网页的布局),用户可以通过平移和缩放来看网页的不同部分。移动版的 Safari 浏览器最新引进了 viewport 这个 meta tag,让网页开发者来控制 viewport 的大小和缩放,其他手机浏览器也基本支持。\r\n

    \r\n

    \r\n width:控制 viewport 的大小,可以指定的一个值,如果 600,或者特殊的值,如 device-width 为设备的宽度(单位为缩放为 100% 时的 CSS 的像素)。\r\n

    \r\n

    \r\n height:和 width 相对应,指定高度。\r\n

    \r\n

    \r\n initial-scale:初始缩放比例,也即是当页面第一次 load 的时候缩放比例。\r\n

    \r\n

    \r\n maximum-scale:允许用户缩放到的最大比例。\r\n

    \r\n

    \r\n minimum-scale:允许用户缩放到的最小比例。\r\n

    \r\n

    \r\n user-scalable:用户是否可以手动缩放。\r\n

    \r\n

    \r\n “viewport”,翻译为中文可以叫做“视区”,大家都知道移动设备的屏幕一般都比PC小很多,webkit浏览器会将一个较大的“虚拟”窗口映射到移动设备的屏幕上,默认的虚拟窗口为980像素宽(目前大部分网站的标准宽度),然后按一定的比例(3:1或2:1)进行缩放。也就是说当我们加载一个普通网页的时候,webkit会先以980像素的浏览器标准加载网页,然后再缩小为490像素的宽度。注意这个缩小是一个全局缩小,也就是页面上的所有元素都会缩小.\r\n

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6675, 'sql-server-calculated-according-to-map-the-latitude-and-longitude-distance-function', 'SQL Server根据地图经纬度计算距离函数', '2015-01-19 03:14:31', '2019-03-26 00:06:20', '

    \r\n 需求背景
    \r\n

    \r\n

    \r\n 前些天客户提出一个这样的要求:一个网上超市微信商城,当用户发送位置的时候,主动推送附近的门店信息。\r\n

    \r\n

    \r\n 需求分析与设计方案
    \r\n

    \r\n

    \r\n 拿到这个需求后,详细的分析了一下,在门店的表中增加两个字段,用来存储酒店所在的经度和纬度,当用户发送位置的时候,后台接受用户所在的经度和纬度,再与数据库中门店的经度和纬度计算一下,就查出来。\r\n

    \r\n

    \r\n 技术实现
    \r\n

    \r\n

    \r\n 定义
    \r\n

    \r\n

    \r\n 为了在数据库中查询两点之间的距离,所以这个函数需要在数据库中定义。 \r\n

    \r\n
    \r\n

    \r\n SET ANSI_NULLS ON\r\n

    \r\n

    \r\n GO\r\n

    \r\n

    \r\n SET QUOTED_IDENTIFIER ON\r\n

    \r\n

    \r\n GO\r\n

    \r\n

    \r\n -- =============================================\r\n

    \r\n

    \r\n -- Author:    <tangyouwei>\r\n

    \r\n

    \r\n -- Create date: <2015-01-19>\r\n

    \r\n

    \r\n -- Description:   计算地球上两个坐标点(经度,纬度)之间距离sql函数\r\n

    \r\n

    \r\n -- Debug      : select  dbo.f_GetDistance(32.651320,110.798380,22.600030,114.034480)\r\n

    \r\n

    \r\n /*\r\n

    \r\n

    \r\n Version:V0.1\r\n

    \r\n

    \r\n Author:tangyouwei\r\n

    \r\n

    \r\n Time:2015.01.19\r\n

    \r\n

    \r\n Description:\r\n

    \r\n

    \r\n 1 计算地球上两个坐标点(经度,纬度)之间距离sql函数\r\n

    \r\n

    \r\n */\r\n

    \r\n

    \r\n -- =============================================\r\n

    \r\n

    \r\n ALTER FUNCTION f_GetDistance\r\n

    \r\n

    \r\n (\r\n

    \r\n

    \r\n     @LatBegin REAL, \r\n

    \r\n

    \r\n     @LngBegin REAL, \r\n

    \r\n

    \r\n     @LatEnd REAL, \r\n

    \r\n

    \r\n     @LngEnd REAL\r\n

    \r\n

    \r\n ) \r\n

    \r\n

    \r\n RETURNS FLOAT  --距离() \r\n

    \r\n

    \r\n AS \r\n

    \r\n

    \r\n BEGIN\r\n

    \r\n

    \r\n DECLARE @Distance REAL \r\n

    \r\n

    \r\n DECLARE @EARTH_RADIUS REAL \r\n

    \r\n

    \r\n SET @EARTH_RADIUS = 6378.137 \r\n

    \r\n

    \r\n DECLARE @RadLatBegin REAL,@RadLatEnd REAL,@RadLatDiff REAL,@RadLngDiff REAL \r\n

    \r\n

    \r\n SET @RadLatBegin = @LatBegin *PI()/180.0 \r\n

    \r\n

    \r\n SET @RadLatEnd = @LatEnd *PI()/180.0 \r\n

    \r\n

    \r\n SET @RadLatDiff = @RadLatBegin - @RadLatEnd \r\n

    \r\n

    \r\n SET @RadLngDiff = @LngBegin *PI()/180.0 - @LngEnd *PI()/180.0 \r\n

    \r\n

    \r\n SET @Distance = 2 *ASIN(SQRT(POWER(SIN(@RadLatDiff/2), 2)+COS(@RadLatBegin)*COS(@RadLatEnd)*POWER(SIN(@RadLngDiff/2), 2))) \r\n

    \r\n

    \r\n SET @Distance = @Distance * @EARTH_RADIUS \r\n

    \r\n

    \r\n SET @Distance = ROUND(@Distance * 10000,5)/10000\r\n

    \r\n

    \r\n SET @Distance=@Distance*1000\r\n

    \r\n

    \r\n RETURN @Distance \r\n

    \r\n

    \r\n END\r\n

    \r\n

    \r\n GO\r\n

    \r\n
    \r\n

    \r\n 使用方法如下\r\n

    \r\n
    \r\n

    \r\n SELECT * FROM 门店表名 WHERE dbo.f_GetDistance(121.4625,31.220937,longitude,latitude) < 5000\r\n

    \r\n
    \r\n\r\n

    \r\n 其他方法\r\n

    \r\n

    \r\n 在SQL2008数据库中,可以直接用geography 数据的函数来解决,见http://msdn.microsoft.com/zh-cn/library/bb933952(v=sql.100).aspx \r\n

    \r\n

    \r\n 关于C#的实现,请参考我的另一篇博文:根据两点经纬度计算距离\r\n

    \r\n

    \r\n  \r\n

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6686, 'sql-server-implement-a-split-function-to-convert-a-string-to-separate-the-data-table', 'SQL Server实现Split函数将字符串分隔转换成数据表', '2015-01-19 06:26:38', '2019-03-26 00:06:04', '

    需求

    \r\n

    C#语言中有内置的字符串函数Split()可以轻松实现分隔将类似 1,2,3,4 的字符串变成数组,然后进行处理,但是SQL Server默认没有这种内置的支持。

    \r\n

    实现

    \r\n

    需要通过自定义函数来实现,思路就是创建表值函数,返回一个分隔后的数据表,然后查询这个返回的表即可。

    \r\n

    代码如下

    \r\n
    \r\n

    SET ANSI_NULLS ON

    \r\n

    GO

    \r\n

    SET QUOTED_IDENTIFIER ON

    \r\n

    GO

    \r\n

    ALTER FUNCTION [dbo].[SplitToTable_Func]

    \r\n

      (

    \r\n

          @SplitString varchar(max),

    \r\n

          @Separator nvarchar(10)=\' \'

    \r\n

      )

    \r\n

     RETURNS @SplitStringsTable TABLE

    \r\n

     (

    \r\n

      [id] int identity(1,1),

    \r\n

      [value] varchar(max)

    \r\n

     )

    \r\n

     AS

    \r\n

     BEGIN

    \r\n

        IF @SplitString\\<>\'\'

    \r\n

        BEGIN

    \r\n

         DECLARE @CurrentIndex int

    \r\n

         DECLARE @NextIndex int

    \r\n

         DECLARE @ReturnText varchar(max)

    \r\n

         SELECT @CurrentIndex=1

    \r\n

         WHILE(@CurrentIndex\\<=len(@SplitString)+1)

    \r\n

             BEGIN

    \r\n

                 SELECT @NextIndex=charindex(@Separator,@SplitString,@CurrentIndex)

    \r\n

                 IF(@NextIndex=0 OR @NextIndex IS NULL)

    \r\n

                     SELECT @NextIndex=len(@SplitString)+1

    \r\n

                     SELECT @ReturnText=substring(@SplitString,@CurrentIndex,@NextIndex-@CurrentIndex)

    \r\n

                     INSERT INTO @SplitStringsTable([value]) VALUES(@ReturnText)

    \r\n

                     SELECT @CurrentIndex=@NextIndex+1

    \r\n

                 END

    \r\n

        END

    \r\n

        RETURN

    \r\n

     END

    \r\n
    \r\n

     调用方法2222

    \r\n
    \r\n

    SELECT * FROM dbo.SplitToTable_Func(\'1,2,3,4\',\',\')

    \r\n
    \r\n

    效果

    \r\n

    \"QQ截图20150119143539\"

    \r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6705, 'sql-server-solution-not-within-a-function-using-table-variables-use-temporary-table-problems', 'SQL Server使用表变量解决不能在函数内使用临时表的问题', '2015-01-19 07:07:08', '2019-03-26 00:05:52', '

    问题重现

    \r\n

    在函数内部想要使用临时表,结果报错:

    \r\n

    \"QQ截图20150119151445\"

    \r\n

    解决方案

    \r\n

    建立表变量,具体方法

    \r\n

    表变量需要先建好表结构,而临时表可以直接插入。

    \r\n
    \r\n

    declare @tablename table

    \r\n

    (

    \r\n

    --表字段

    \r\n

    )

    \r\n

    insert into @tablename select ......

    \r\n

    而临时表可以直接 select * into #tablename.......

    \r\n
    \r\n

    我的案例

    \r\n

    还是承接的这篇博文:SQL Server根据地图经纬度计算距离函数

    \r\n

    ,只不过把经纬度换成了坐标,因此需要转换,代码如下:

    \r\n
    \r\n

    SET ANSI_NULLS ON

    \r\n

    GO

    \r\n

    SET QUOTED_IDENTIFIER ON

    \r\n

    GO

    \r\n

    -- =============================================

    \r\n

    -- Author:   

    \r\n

    -- Create date: <2015-01-19>

    \r\n

    -- Description:   计算地球上两个坐标点(经度,纬度)之间距离sql函数

    \r\n

    -- Debug      : select  dbo.f_GetDistance(\'32.651320,110.798380\',\'22.600030,114.034480\')

    \r\n

    /*

    \r\n

    Version:V0.1

    \r\n

    Author:tangyouwei

    \r\n

    Time:2015.01.19

    \r\n

    Description:

    \r\n

    1 计算地球上两个坐标点(经度,纬度)之间距离sql函数

    \r\n

    */

    \r\n

    -- =============================================

    \r\n

    ALTER FUNCTION f_GetDistance

    \r\n

    (

    \r\n

       @startMapPoint VARCHAR(20),

    \r\n

       @endMapPoint VARCHAR(20)

    \r\n

    )

    \r\n

    RETURNS FLOAT  --距离()

    \r\n

    AS

    \r\n

    BEGIN

    \r\n

    --坐标转换成经纬度

    \r\n

    declare @temp1 table(id INT,value varchar(20))--表变量

    \r\n

    declare @temp2 table(id INT,value varchar(20))--表变量

    \r\n

    INSERT INTO @temp1 SELECT * FROM dbo.SplitToTable_Func(@startMapPoint,\',\')

    \r\n

    INSERT INTO @temp2 SELECT * FROM dbo.SplitToTable_Func(@endMapPoint,\',\')

    \r\n

    DECLARE @LatBegin REAL

    \r\n

    DECLARE    @LngBegin REAL

    \r\n

    DECLARE    @LatEnd REAL

    \r\n

    DECLARE    @LngEnd REAL

    \r\n

    SET @LatBegin=(SELECT value FROM @temp1 WHERE id=1)

    \r\n

    SET @LngBegin=(SELECT value FROM @temp1 WHERE id=2)

    \r\n

    SET @LatEnd=(SELECT value FROM @temp2 WHERE id=1)

    \r\n

    SET @LngEnd=(SELECT value FROM @temp2 WHERE id=2)

    \r\n

    --计算距离

    \r\n

    DECLARE @Distance REAL

    \r\n

    DECLARE @EARTH_RADIUS REAL

    \r\n

    SET @EARTH_RADIUS = 6378.137

    \r\n

    DECLARE @RadLatBegin REAL,@RadLatEnd REAL,@RadLatDiff REAL,@RadLngDiff REAL

    \r\n

    SET @RadLatBegin = @LatBegin *PI()/180.0

    \r\n

    SET @RadLatEnd = @LatEnd *PI()/180.0

    \r\n

    SET @RadLatDiff = @RadLatBegin - @RadLatEnd

    \r\n

    SET @RadLngDiff = @LngBegin *PI()/180.0 - @LngEnd *PI()/180.0

    \r\n

    SET @Distance = 2 *ASIN(SQRT(POWER(SIN(@RadLatDiff/2), 2)+COS(@RadLatBegin)*COS(@RadLatEnd)*POWER(SIN(@RadLngDiff/2), 2)))

    \r\n

    SET @Distance = @Distance * @EARTH_RADIUS

    \r\n

    SET @Distance = ROUND(@Distance * 10000,5)/10000

    \r\n

    SET @Distance=@Distance*1000

    \r\n

    RETURN @Distance

    \r\n

    END

    \r\n

    GO

    \r\n

     

    \r\n
    \r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6715, '20150119215010', '20150119215010', '2015-01-19 13:50:04', '2019-03-25 21:29:22', '有条理的做好每一件事。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6716, 'learning-csharp-note-006-c-difference-between-const-and-readonly', 'c#学习笔记006:c#中const与readonly区别', '2013-01-20 01:58:38', '2019-03-25 21:29:22', '

    \r\n 概述
    \r\n

    \r\n

    \r\n const 的概念就是一个包含不能修改的值的变量。
    \r\n常数表达式是在编译时可被完全计算的表达式。因此不能从一个变量中提取的值来初始化常量。
    \r\n如果 const int a = b+1;b是一个变量,显然不能再编译时就计算出结果,所以常量是不可以用变量来初始化的。\r\n

    \r\n

    \r\n 但是下面的代码是合法的:\r\n

    \r\n
    \r\n

    \r\n  \r\n

    \r\n

    \r\n const int a = 1;\r\n

    \r\n

    \r\n const int b = a + 3;\r\n

    \r\n
    \r\n

    \r\n 这是因为a是const的,也就是说,在编译的时候编译器已经知道a的值是1,并且不能改变,运行第二句的时候,编译器会自动计算出b的值。使用JustDecompile,我们会看到,代码是这样:\r\n

    \r\n
    \r\n

    \r\n  \r\n

    \r\n

    \r\n using System;\r\n

    \r\n

    \r\n \r\n

    \r\n

    \r\n namespace Test\r\n

    \r\n

    \r\n {\r\n

    \r\n

    \r\n     internal class Program\r\n

    \r\n

    \r\n     {\r\n

    \r\n

    \r\n         public Program()\r\n

    \r\n

    \r\n         {\r\n

    \r\n

    \r\n         }\r\n

    \r\n

    \r\n \r\n

    \r\n

    \r\n         private static void Main(string[] args)\r\n

    \r\n

    \r\n         {\r\n

    \r\n

    \r\n             Console.WriteLine(4);\r\n

    \r\n

    \r\n             Console.ReadKey();\r\n

    \r\n

    \r\n         }\r\n

    \r\n

    \r\n     }\r\n

    \r\n

    \r\n }\r\n

    \r\n
    \r\n

    \r\n
    \r\nreadonly 允许把一个字段设置成常量,但可以执行一些运算,可以确定它的初始值。
    \r\n因为 readonly 是在计算时执行的,当然它可以用某些变量初始化。
    \r\nreadonly 是实例成员,所以不同的实例可以有不同的常量值,这使readonly更灵活。\r\n

    \r\n

    \r\n 分析
    \r\n

    \r\n

    \r\n
    \r\nreadonly 关键字与 const 关键字不同。
    \r\n1. const 字段只能在该字段的声明中初始化。
    \r\n   readonly 字段可以在声明或构造函数中初始化。因此,根据所使用的构造函数,readonly 字段可能具有不同的值。
    \r\n2. const 字段是编译时常数,而 readonly 字段可用于运行时常数。
    \r\n3. const 默认就是静态的,而 readonly 如果设置成静态的就必须显示声明。
    \r\n4.const 对于引用类型的常数,可能的值只能是 string 和 null。
    \r\n   readonly可以是任何类型\r\n

    \r\n

    \r\n
    \r\n总结
    \r\n

    \r\n

    \r\n
    \r\nconst只能在初期就使用常量初始化好。对于每一次编译后的结果,const的值是固定的,而readonly的值是可以在运行的时候才确定值的。\r\n

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6724, 'html5-simulation-android-pullups-dropdown-refresh', '002:Html5模拟android上拉/下拉刷新', '2015-01-20 02:57:54', '2019-03-25 21:29:22', '

    \r\n  \r\n

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6725, 'javascript-jquery-plugin-development-001-introduction', 'JavaScript/JQuery插件化开发001:开篇', '2015-01-21 01:17:18', '2019-03-26 00:05:37', '

    \r\n 开篇分析\r\n

    \r\n

    \r\n 关于JavaScript”的插件式开发,我想很多人对”插件“这个词并不陌生,\r\n

    \r\n

    \r\n 有的人可能叫“组件”或“部件”,这不重要,关键是看如何设计,如何做一个全方位的考量,这是本文的重点阐述的概念。我想大家对\r\n

    \r\n

    \r\n “jQuery插件的方式”有一定的了解,我们结合这个话题一起讨论一下,最终给出相关的实现方案,来不断提高自己的谁能力。\r\n

    \r\n

    \r\n            \"\"\r\n

    \r\n

    \r\n  \r\n

    \r\n

    \r\n 进入插件正题\r\n

    \r\n

    \r\n 一般来说,jQuery插件的开发分为两种:一种是挂在jQuery命名空间下的全局函数,也可称为静态方法。\r\n

    \r\n

    \r\n 另一种是jQuery对象级别的方法,即挂在jQuery原型下的方法,这样通过选择器获取的jQuery对象实例也能共享该方法。\r\n

    \r\n

    \r\n 类级别的插件开发\r\n

    \r\n

    \r\n 类级别的插件开发最直接的理解就是给\"jQuery\"类添加类方法,可以理解为添加静态方法。典型的例子就是\"$.ajax()\"这个函数,将函数定义于jQuery的命名空间中。关于类级别的插件开发可以采用如下几种形式进行扩展:\r\n

    \r\n

    \r\n 1.1添加一个全局函数,我们只需如下定义,看代码: \r\n

    \r\n

    \r\n 参考\r\n

    \r\n

    \r\n http://www.cnblogs.com/bigbearbb/p/4237282.html\r\n

    \r\n

    \r\n  \r\n

    \r\n

    \r\n  \r\n

    \r\n

    \r\n  \r\n

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6741, '20150124223556', '20150124223556', '2015-01-24 14:35:56', '2019-03-25 21:29:22', '开始使用markdown写博客。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6764, 'cross-platform-mobile-app-development-001-visual-studio-build-apache-cordova-2013-development-environment', '跨平台移动APP开发系列001:Visual Studio 2013搭建Apache Cordova开发环境', '2015-01-26 03:24:55', '2019-03-25 21:29:22', '

    什么是Cordova

    \r\n\"cordova-logo\"\r\n

    Apache的Cordova是一套设备API,许一个移动应用程序开发人员使用JavaScript访问本机设备功能,如相机或加速。结合UI框架,如jQuery Mobile的或Dojo Mobile或Sencha Touch,这样就可以只用HTML,CSS和JavaScript开发的智能手机应用程序。

    \r\n

    Cordova可以做什么

    \r\n

    当使用Cordova API的时候,应用开发人员可以在不使用本地代码( Java中,Objective-C,等等))的情况下开发app,这些应用程序最终托管的在本地,而不是在远程HTTP服务器)。

    \r\n

    环境搭建

    \r\n

    安装Microsoft Visual Studio Ultimate 2013 with Update 4,下载地址:

    \r\n

    Visual Studio 2013 Update 4 (Visual Studio 2013.4)

    \r\n

    Microsoft Visual Studio Ultimate 2013 with Update 4

    \r\n

    Microsoft Visual Studio Team Foundation Server 2013 with Update 4

    \r\n

    Visual Studio Downloads

    \r\n

    Overview of Visual Studio 2013 updates

    \r\n

    Hello Word

    \r\nhttp://aehyok.com/Blog/Detail/75.html\r\nhttp://www.cnblogs.com/cnshen/p/4128120.html\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6773, 'what-is-the-granularity', '什么是粒度', '2014-01-26 08:00:04', '2019-03-25 21:29:22', '

    简单说粒度就是事实表里测量值的测量‘频率’。 比如说,销售库里的销售额,可以是一天一个值,也可以是一个月一个值,甚至一年一个值,这就是相对于时间维度表的力度;可以是一个商品一个值,也可以是一类商品一个值,这就是相对于商品的粒度。

    \r\n

    粒度就是同一维度下,数据的粗细程度,考虑到时间维度在数据仓库中相对比较特殊,另外举个例子。
    以“组织结构”为例,比如我们的一个层级结构式:总公司,分公司,部门,科室。这就是不同的粒度级别。

    \r\n

    实际应用中,比如有人问,你的某个报表粒度是怎样的。
    我们可以说,组织结构我们的报表呈现是到分公……

    \r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6776, 'the-callback-function-callback', '回调函数(callback)', '2014-01-26 08:13:42', '2019-03-25 21:29:22', '

    \"01300000291746125109739737755\"

    \r\n

    实例理解

    \r\n

    你到一个商店买东西,刚好你要的东西没有货,于是你在店员那里留下了你的电话,过了几天店里有货了,店员就打了你的电话,然后你接到电话后就到店里去取了货。在这个例子里,你的电话号码就叫回调函数,你把电话留给店员就叫登记回调函数,店里后来有货了叫做触发了回调关联的事件,店员给你打电话叫做调用回调函数,你到店里去取货叫做响应回调事件。回答完毕。

    \r\n

    专业解释

    \r\n

    这个是程序上的概念。
    本质上是叫别人做事,传进去的额外信息。

    \r\n

    比如,A叫B做事,根据粒度不同,可以理解成A函数调用B函数,或者A类使用B类,或者A组件使用B组件等等。反正就是A叫B做事。

    \r\n

    当B做这件事情的时候,自身的需要的信息不够,而A又有。就需要A从外面传进来,或者B做着做着主动向外面申请。对于B来说,一种被动得到信息,一种是主动去得到信息,有人给这两种方式术语,叫信息的push,和信息的pull。

    \r\n

    接着,A调用B,A向B传参数。int max(int a, int b); 要使用这函数max, 得到两者最大的值, 外面就要传进来a, b。这个好理解。

    \r\n

    再跟着,就来到计算机中比较诡异的地方。也就是代码(code)和数据(data)的统一,这是一个槛,如果不打通这个,很多概念就不清楚。我们常常说计算机程序分成code和data两部分。很多人就会觉得,code是会运行的,是动的,data是给code使用,是静态的,这是两种完全不同的东西。

    \r\n

    其实code只是对行为的一种描述,比如有个机器人可以开灯,关灯,扫地。跟着我要机器人开灯,扫地,关灯。如果跟机器人约定好,0表示开灯,1表示关灯,2表示扫地。我发出指令,0 1 2 1 0。跟着就可以控制机器人开灯,扫地,关灯。再约定用二进制表示,两位一个指令,就有一个数字串,0001110100,这个时候0001110100这串数字就描述了机器人的一系列动作,这个就是从一方面理解是code,可以它可以控制机器人的行为。但另一方面,它可以传递,可以记录,可以修改,也就是数据。只要大家都协商好,code就可以编码成data, 将data解释运行的时候,也变成了code。

    \r\n

    这个地方扯开了。我自己是不区分code和data的,统一称为信息。那既然int max(int a, int b)中int,double等表示普通data的东西可以传递进去,凭什么表示code的函数就不可以传进去了。有些语言确实是不区分的,它的function(表示code)跟int, double的地位是一样的。这种语言就为函数是第一类值。

    \r\n

    但问题是,有些语言是不能存储函数,不能动态创建函数,不能动态销毁函数。(这里函数是已经是广义的了,用来表示代码code)。只能存储一个指向函数的指针,这种语言称为函数是第二类值。

    \r\n

    另外有些语言不单可以传递函数,函数里面又用到一些外部信息(包括code, data)。那些语言可以将函数跟函数所用到的信息一起传递存储。这种将函数和它所用的信息作为一个整体,就为闭包。

    \r\n

    再次声明,将代码和数据打通,统一起来,是一个槛。过了这个槛,很多难以理解的概念就会清晰很多。比如一些修改自身的程序啊,数据驱动啊,先设计数据再写程序等等。

    \r\n

    来到这里,其实已经没有什么好说的了。回调函数也就是是A让B做事,B做着做着,信息不够,不知道怎么做了,就再让外面处理。

    \r\n

    比如排序,A让B排序,B会做排序,但排序需要知道哪个比哪个大,这点B自己不知道,就需要A告诉它。而这种判断那个大,本身是一种动作,既然C语言中不可以传进第一值的函数,就设计成传递第二值的函数指针,这个函数指针就是A传向B的信息,用来表示一个行为。这里本来A调用B的,结果B又调用了A告诉它的信息,也就叫callback。

    \r\n

    再比如A让B监听系统的某个消息,比如敲了哪个键。跟着B监听到了,但它不知道怎么去处理这个消息,就给外面关心这个消息,又知道怎么去处理这个消息的人去处理,这个处理过程本事是个行为,既然这个语言不可以传递函数,又只能传一个函数指针了。跟着有些人有会引申成,什么注册啊,通知啊等等等。假如B做监听,C, D, E, F, G, H告诉B自己有兴趣知道这消息,那B监听到了就去告诉C,D,E,F,G等人了,这样通知多人了,就叫广播。

    \r\n

    其实你理解了,根本不用去关心术语的。术语是别人要告诉你啊,或者你去告诉人啊,使用的一套约定的词语。本质上就个东西,结果会有很多术语的。

    \r\n

    跟着再将回调的概念进化,比如某人同时关心A,B,C,D,E,F事件,并且这些事件是一组的,比如敲键盘,鼠标移动,鼠标点击等一组。将一组事件结合起来。在有些语言就变成一个接口,接口有N个函数。有些语言就映射成一个结构,里面放着N个函数指针。跟着就不是将单个函数指针传进去,而是将接口,或者函数指针的结构传进去。这些根据不同的用途,有些人叫它为代理啊,监听者啊,观察者啊等等。
    编辑于 2014-01-14 10 条评论
    桥头堡,追求知识
    赵勇杰、Roy Li、Bob Li 等人赞同
    什么是回调函数?

    \r\n

    我们绕点远路来回答这个问题。

    \r\n

    编程分为两类:系统编程(system programming)和应用编程(application programming)。所谓系统编程,简单来说,就是编写库;而应用编程就是利用写好的各种库来编写具某种功用的程序,也就是应用。系统程序员会给自己写的库留下一些接口,即API(application programming interface,应用编程接口),以供应用程序员使用。所以在抽象层的图示里,库位于应用的底下。

    \r\n

    当程序跑起来时,一般情况下,应用程序(application program)会时常通过API调用库里所预先备好的函数。但是有些库函数(library function)却要求应用先传给它一个函数,好在合适的时候调用,以完成目标任务。这个被传入的、后又被调用的函数就称为回调函数(callback function)。

    \r\n

    打个比方,有一家旅馆提供叫醒服务,但是要求旅客自己决定叫醒的方法。可以是打客房电话,也可以是派服务员去敲门,睡得死怕耽误事的,还可以要求往自己头上浇盆水。这里,“叫醒”这个行为是旅馆提供的,相当于库函数,但是叫醒的方式是由旅客决定并告诉旅馆的,也就是回调函数。而旅客告诉旅馆怎么叫醒自己的动作,也就是把回调函数传入库函数的动作,称为登记回调函数(to register a callback function)。如下图所示(图片来源:维基百科):

    \r\n

    可以看到,回调函数通常和应用处于同一抽象层(因为传入什么样的回调函数是在应用级别决定的)。而回调就成了一个高层调用底层,底层再回过头来调用高层的过程。(我认为)这应该是回调最早的应用之处,也是其得名如此的原因。

    \r\n

    回调机制的优势

    \r\n

    从上面的例子可以看出,回调机制提供了非常大的灵活性。请注意,从现在开始,我们把图中的库函数改称为中间函数了,这是因为回调并不仅仅用在应用和库之间。任何时候,只要想获得类似于上面情况的灵活性,都可以利用回调。

    \r\n

    这种灵活性是怎么实现的呢?乍看起来,回调似乎只是函数间的调用,但仔细一琢磨,可以发现两者之间的一个关键的不同:在回调中,我们利用某种方式,把回调函数像参数一样传入中间函数。可以这么理解,在传入一个回调函数之前,中间函数是不完整的。换句话说,程序可以在运行时,通过登记不同的回调函数,来决定、改变中间函数的行为。这就比简单的函数调用要灵活太多了。请看下面这段Python写成的回调的简单示例:

    \r\n

    even.py

    \r\n

    回调函数1

    \r\n

    生成一个2k形式的偶数

    \r\n

    def double(x):
    return x * 2

    \r\n

    回调函数2

    \r\n

    生成一个4k形式的偶数

    \r\n

    def quadruple(x):
    return x * 4

    \r\n

    callback_demo.py
    from even import *

    \r\n

    中间函数

    \r\n

    接受一个生成偶数的函数作为参数

    \r\n

    返回一个奇数

    \r\n

    def getOddNumber(k, getEvenNumber):
    return 1 + getEvenNumber(k)

    \r\n

    起始函数,这里是程序的主函数

    \r\n

    def main():
    k = 1
    #当需要生成一个2k+1形式的奇数时
    i = getOddNumber(k, double)
    print(i)
    #当需要一个4k+1形式的奇数时
    i = getOddNumber(k, quadruple)
    print(i)
    #当需要一个8k+1形式的奇数时
    i = getOddNumber(k, lambda x: x * 8)
    print(i)

    \r\n

    if name == "main":
    main()

    \r\n

    运行callback_demp.py,输出如下:
    3
    5
    9

    \r\n

    上面的代码里,给getOddNumber传入不同的回调函数,它的表现也不同,这就是回调机制的优势所在。值得一提的是,上面的第三个回调函数是一个匿名函数。

    \r\n

    易被忽略的第三方

    \r\n

    通过上面的论述可知,中间函数和回调函数是回调的两个必要部分,不过人们往往忽略了回调里的第三位要角,就是中间函数的调用者。绝大多数情况下,这个调用者可以和程序的主函数等同起来,但为了表示区别,我这里把它称为起始函数(如上面的代码中注释所示)。

    \r\n

    之所以特意强调这个第三方,是因为我在网上读相关文章时得到一种印象,很多人把它简单地理解为两个个体之间的来回调用。譬如,很多中文网页在解释“回调”(callback)时,都会提到这么一句话:“If you call me, I will call you back.”我没有查到这句英文的出处。我个人揣测,很多人把起始函数和回调函数看作为一体,大概有两个原因:第一,可能是“回调”这一名字的误导;第二,给中间函数传入什么样的回调函数,是在起始函数里决定的。实际上,回调并不是“你我”两方的互动,而是ABC的三方联动。有了这个清楚的概念,在自己的代码里实现回调时才不容易混淆出错。

    \r\n

    另外,回调实际上有两种:阻塞式回调和延迟式回调。两者的区别在于:阻塞式回调里,回调函数的调用一定发生在起始函数返回之前;而延迟式回调里,回调函数的调用有可能是在起始函数返回之后。这里不打算对这两个概率做更深入的讨论,之所以把它们提出来,也是为了说明强调起始函数的重要性。网上的很多文章,提到这两个概念时,只是笼统地说阻塞式回调发生在主调函数返回之前,却没有明确这个主调函数到底是起始函数还是中间函数,不免让人糊涂,所以这里特意说明一下。另外还请注意,本文中所举的示例均为阻塞式回调。延迟式回调通常牵扯到多线程,我自己还没有完全搞明白,所以这里就不多说了。
    前言
    在Java社区的各种开源工具中,回调方法的使用俯拾即是。所以熟悉回调方法无疑能加速自己对开源轮子的掌握。
    网上搜了一些文章,奈何对回调方法的介绍大多只停留在什么是回调方法的程度上。本篇文章尝试从回调方法怎么来的、为什么要使用回调方法以及在实际项目中如何使用等方面来介绍下。
    场景
    场景选择的得当与否,很影响读者的继续阅读的兴趣甚至理解的主动性(长期作为互联网技术博文读者的我,深有感触)。
    好场景私以为是:熟悉且简单。
    本例小心翼翼选择的场景是:写作业。(hope you like)
    自己写
    注:写作业这个动作至少交代三个方面:谁,什么动作(写),写什么。
    下面先从(有个学生,写,作业)开始。

    \r\n

    1. 有个学生

    \r\n

    Student student = new Student();

    \r\n

    2. 该学生有写作业这个动作需要执行

    \r\n

    student.doHomeWork(someHomeWork);

    \r\n

    3. 注意到这个写作业这个动作是需要得到入参“作业”的后才能进行的。所以给这个学生new了个简单的题目做。

    \r\n

    String aHomeWork = "1+1=?";
    student.doHomeWork(aHomeWork);
    至此,完成写作业的动作。

    \r\n

    完整代码
    public class Student {

    \r\n
    public void doHomeWork(String homeWork) {\r\n     System.out.println("作业本");\r\n    if("1+1=?".equals(homeWork)) {\r\n        System.out.println("作业:"+homeWork+" 答案:"+"2");\r\n    } else {\r\n        System.out.println("作业:"+homeWork+" 答案:"+"不知道~~");\r\n    }\r\n}\r\n\r\npublic static void main(String[] args) {\r\n    Student student = new Student();\r\n\r\n    String aHomeWork = "1+1=?";\r\n    student.doHomeWork(aHomeWork);\r\n}
    \r\n

    }
    程序执行
    作业本
    作业:1+1=? 答案:2
    我们一定要把焦点聚焦到,”写作业“这个需求上面。
    该学生写作业的方法是现成的,但是需要有作业作为入参,怎么获取作业才是完成动作的关键。希望这点能深深印入我们的脑海。

    \r\n

    让室友帮忙解答
    上面的例子中该同学自己调用自己的方法,把收到的homework直接写了。
    但是现实可能会出现各种各样的问题导致该同学不能(xiang)自己来做。比如他想玩游戏或者有约会。所以他拜托了他的好室友(roommate)来帮忙写下。该怎么实现呢。

    \r\n

    1. 因为室友帮忙写,所以在doHomeWork动作里面,就不需要有逻辑判断的代码,因为舍友会直接把答案写进来。改成:

    \r\n

    student.doHomeWork(aHomeWork, theAnswer);

    \r\n

    上句中做作业的动作支持传入“作业”和“答案”,有了这两个,就说明能做好作业了。

    \r\n

    其中aHomeWork作业是已知的,但是theAnswer这个答案却是室友提供的。

    \r\n

    室友怎么才能提供答案呢,最简单是,室友这个对象直接提供一个传入作业,传出答案的方法,这样该同学就可以直接调用了。

    \r\n

    RoomMate roomMate = new RoomMate();
    String theAnswer = roomMate.getAnswer(aHomeWork);
    student.doHomeWork(aHomeWork, theAnswer);
    完整代码
    public class Student {

    \r\n
    public void doHomeWork(String homeWork, String answer) {\r\n    System.out.println("作业本");\r\n    if(answer != null) {\r\n        System.out.println("作业:"+homeWork+" 答案:"+ answer);\r\n    } else {\r\n        System.out.println("作业:"+homeWork+" 答案:"+ "(空白)");\r\n    }\r\n\r\n}\r\n\r\npublic static void main(String[] args) {\r\n    Student student = new Student();\r\n\r\n    String aHomeWork = "1+1=?";\r\n\r\n    RoomMate roomMate = new RoomMate();\r\n    String theAnswer = roomMate.getAnswer(aHomeWork);\r\n    student.doHomeWork(aHomeWork, theAnswer);\r\n}
    \r\n

    }
    public class RoomMate {

    \r\n
    public String getAnswer(String homework) {\r\n    if("1+1=?".equals(homework)) {\r\n        return "2";\r\n    } else {\r\n        return null;\r\n    }\r\n}
    \r\n

    }
    程序执行
    作业本
    作业:1+1=? 答案:2
    怒,说好的回调方法呢~~
    因为到目前为止,不需要使用回调方法。
    技术总是伴随新的需求出现的。
    好,给你新的需求。
    注意重点来了
    我们回顾下这两行代码

    \r\n

    室友写好作业

    \r\n

    String theAnswer = roomMate.getAnswer(aHomeWork);

    \r\n

    该同学直接抄答案,完成作业

    \r\n

    student.doHomeWork(aHomeWork, theAnswer);
    该同学想了想,你给了答案有屁用,还得要我自己誊写到作业本上面去(执行自己的做作业方法)。
    你就不能直接调用我的做作业方法帮我把答案写好,把作业做完得了。
    让室友直接把作业写了
    经不住该同学的软磨硬泡,“中国好室友”答应了。怎么实现呢。
    再回顾下做作业的全过程

    \r\n

    待解决的作业

    \r\n

    String aHomeWork = "1+1=?";

    \r\n

    室友写出答案

    \r\n

    String theAnswer = roomMate.getAnswer(aHomeWork);

    \r\n

    该同学调用,自己把答案写到作业本。(也即是这个步骤不给调用了)

    \r\n

    student.doHomeWork(aHomeWork, theAnswer);

    \r\n

    做作业必须得调用这个方法,而根据需求这个方法必须由室友去调用。那很显然,该室友得保持一个该同学的引用,才能正常调用啊。

    \r\n

    灯灯灯~

    \r\n

    室友说,那你在调用getAnswer方法的时候,除了传入作业,还需要把自己的引用放里面。这样我做完了,直接调用你的做作业方法就行了。

    \r\n

    roomMate.getAnswer(aHomeWork,student);
    完整代码
    public class Student {

    \r\n
    public void doHomeWork(String homeWork, String answer) {\r\n    System.out.println("作业本");\r\n    if(answer != null) {\r\n        System.out.println("作业:"+homeWork+" 答案:"+ answer);\r\n    } else {\r\n        System.out.println("作业:"+homeWork+" 答案:"+ "(空白)");\r\n    }\r\n\r\n}\r\n\r\npublic static void main(String[] args) {\r\n    Student student = new Student();\r\n\r\n    String aHomeWork = "1+1=?";\r\n\r\n    RoomMate roomMate = new RoomMate();\r\n    roomMate.getAnswer(aHomeWork,student);\r\n}
    \r\n

    }
    public class RoomMate {

    \r\n
    public void getAnswer(String homework, Student student) {\r\n    if("1+1=?".equals(homework)) {\r\n        student.doHomeWork(homework, "2");\r\n    } else {\r\n        student.doHomeWork(homework, "(空白)");\r\n    }\r\n}
    \r\n

    }
    执行程序
    作业本
    作业:1+1=? 答案:2

    \r\n

    回调方法
    在上述“让室友直接把作业写了”的例子中,其实已经体现了回调的意思。
    场景的核心在于这位学生要把作业给做了。
    简单点描述:这位学生告诉室友要做什么作业,并把自己的引用也给了室友。该室友得到作业,做完后直接引用该学生并调用其做作业的方法,完成代写作业的任务。
    稍微复杂点描述:
    该学生做作业的方法有两个入参,一个是作业题目(已知),一个是作业答案(未知)。
    室友为了帮助他写作业提供了一个方法,该方法有两个入参,一个是作业题目,一个是该学生的引用(解出答案得知道往哪写)。
    程序执行时,该学生只要调用室友的代写作业方法就行了。一旦室友得到答案,因为有该学生的引用,所以直接找到对应方法,帮助其完成作业。
    再复杂点描述:
    学生调用室友的替写作业方法,注册了题目和自己的引用。室友的替写作业方法被调用,则会根据题目完成作业后,再回调该同学写作业方法,完成作业。
    再抽象点描述:
    类A调用类B的方法b(传入相关信息),类B的方法在执行完后,会将结果写到(再回调)类A的方法a,完成动作。(其实方法a就是传说中的回调方法啦)
    最抽象的描述:
    调用,回调。

    \r\n

    接口方式的回调方法
    常常使用回调方法的同学可能会说,我从来也没见过直接把对象的引用写到第一次调用方法里面的。
    嗯,是的,下面就来填上述例子留下的“天坑”(实际项目中常见到)。
    问题:在调用方法中直接传对象引用进去有什么不好?
    只说一点,只是让别人代写个方法,犯得着把自己全部暴露给别人吗。万一这个别人是竞争对手的接口咋办。这就是传说中的后面代码吗(/tx)。
    总之这样做是非常不安全的。
    因此,最常规的《调用,回调》实现,是(你已经猜到了)使用接口作为引用(说的不严谨)传入调用的方法里面。
    我承认,怎么将思路跳转到使用接口的花了我好长时间。
    我们再看RoomMate类的getAnswer方法。
    public class RoomMate {

    \r\n
    public void getAnswer(String homework, Student student) {\r\n    if("1+1=?".equals(homework)) {\r\n        student.doHomeWork(homework, "2");\r\n    } else {\r\n        student.doHomeWork(homework, "(空白)");\r\n    }\r\n}
    \r\n

    }
    关键在于,该方法的用途是来解决某学生提出的某个问题。答案是通过学生的doHomeWork方法回调传回去的。那假设有个工人也有问题,这位室友该怎么解决呢。再开个方法,专门接收工人的引用作为传参?当然不用,只要你这个引用包含了doHomeWork()方法,那么不论你是工人、警察还是环卫工人,直接调用getAnswer()方法就能解决你提的问题。
    至此我们的思路达到了:所有的对象要有同一个方法,所以自热而然就引出了接口概念。只要这些对象都实现了某个接口就行了,这个接口的作用,仅仅是用来规定那个做作业的方法长什么样。这样工人实现了该接口,那么就有了默认继承的做作业方法。工人再把自己的引用抛给该室友的时候,这个室友就不需要改动任何代码,直接接触答案,完成任务了。
    创建一个做作业的接口,专门规定,需要哪些东西(问题和答案)就能做作业.
    public interface DoHomeWork {
    void doHomeWork(String question, String answer);
    }
    改动下中国好室友的解答方法。任意一个实现了DoHomeWork 接口的someone,都拥有doHomeWork(String question,String answer)的方法。这个方法就是上面已经提到的“回调方法”。someone先调用下好室友的getAnswer()方法,把问题和自己传进来(此为调用),好室友把问题解答出之后,调用默认提供的方法,写完作业。
    思考下,因为是以接口作为参数类型的约定,在普通对象upcast向上转型之后将只暴露接口描述的那个方法,别人获取到这个引用,也只能使用这个(回调)方法。至此,遗留的重大安全隐患重要解决。
    完整代码
    public class RoomMate {

    \r\n
    public void getAnswer(String homework, DoHomeWork someone) {\r\n    if("1+1=?".equals(homework)) {\r\n        someone.doHomeWork(homework, "2");\r\n    } else {\r\n        someone.doHomeWork(homework, "(空白)");\r\n    }\r\n}
    \r\n

    }
    package org.futeng.designpattern.callback.test1;

    \r\n

    public class Worker implements DoHomeWork {

    \r\n
    @Override\r\npublic void doHomeWork(String question, String answer) {\r\n    System.out.println("作业本");\r\n    if(answer != null) {\r\n        System.out.println("作业:"+question+" 答案:"+ answer);\r\n    } else {\r\n        System.out.println("作业:"+question+" 答案:"+ "(空白)");\r\n    }\r\n}\r\n\r\npublic static void main(String[] args) {\r\n    Worker worker = new Worker();\r\n    String question = "1+1=?";\r\n\r\n    new RoomMate().getAnswer(question, worker);\r\n\r\n}
    \r\n

    }
    执行程序
    作业本
    作业:1+1=? 答案:2
    至此,调用+回调的文章是不是写完了呢。
    咳咳,还木有。大家喝点茶再忍耐下。(我都写一天了 - -)

    \r\n

    常规使用之匿名内部类
    作为平凡的屁民,实用主义是我们坚持的生存法则。
    所以凡事用不到的技术都可以不学,凡事学了却不用的技术等于白学。
    我们之前已经定性,中国好室友RoomMate类拥有接受任何人任何问题挑战的潜质。
    自从好室友出名之后,有个不知道什么工作(类型)的人也来问问题。反正只要实现了回调接口,好室友都能调用你默认继承的回调方法,那就放马过来吧。
    package org.futeng.designpattern.callback.test1;

    \r\n

    public class RoomMate {

    \r\n
    public void getAnswer(String homework, DoHomeWork someone) {\r\n    if("1+1=?".equals(homework)) {\r\n        someone.doHomeWork(homework, "2");\r\n    } else {\r\n        someone.doHomeWork(homework, "(空白)");\r\n    }\r\n}\r\n\r\npublic static void main(String[] args) {\r\n\r\n    RoomMate roomMate = new RoomMate();\r\n\r\n    roomMate.getAnswer("1+1=?", new DoHomeWork() {\r\n\r\n        @Override\r\n        public void doHomeWork(String question, String answer) {\r\n            System.out.println("问题:"+question+" 答案:"+answer);\r\n        }\r\n    });\r\n}
    \r\n

    }
    看到稍显奇怪的roomMate.getAnswer("1+1=?", new DoHomeWork() {的哪一行,其实这里new的是DoHomeWork接口的一个匿名内部类。这里我想大家应该自己动脑想想,调用+反调,这个过程是怎么实现的了。
    至于是否使用匿名内部类是根据具体使用场景决定的。普通类不够直接,匿名内部类的语法似乎也不够友好。
    开源工具中对回调方法的使用
    上述匿名内部类的示例才是开源工具中常见到的使用方式。
    调用roomMate解答问题的方法(传进去自己的引用),roomMate解决问题,回调引用里面包含的回调方法,完成动作。
    roomMate就是个工具类,“调用”这个方法你传进去两个参数(更多也是一个道理),什么问题,问题解决了放哪,就行了。该“调用”方法根据问题找到答案,就将结果写到你指定放置的位置(作为回调方法的入参)。
    试想下,“中国好室友”接收的问题是SQL语句,接收的放置位置是我的引用。你解决问题(执行完SQL),将答案(SQL的反馈结果)直接写入我的回调方法里面。回调方法里面可能包括一个个的字段赋值。但是在调用层面隐藏了很多细节的处理。这是回调方法的一个小小的优势。再换句话说,不需要拿到执行完SQL之后的返回结果一个个来赋值。
    SQL的例子
    public static List queryPerson() {
    QueryRunner queryRunner = new QueryRunner(DataSourceSupport.getDataSource());

    \r\n
        return queryRunner.query(" select t.name, t.age from person t ", new ResultSetHandler<List<Person>>(){\r\n\r\n        List list = new ArrayList<Person>();\r\n        @Override\r\n        public List<Person> handle(ResultSet rs) throws SQLException {\r\n\r\n            while(rs.next()) {\r\n                Person person = new Person();\r\n                person.setName(rs.getString(0));\r\n                person.setAge(rs.getInt(1));\r\n                list.add(person);\r\n            }\r\n            return list;\r\n        }\r\n    });\r\n}
    \r\n

    回调方法的优势
    回调方法最大的优势在于,异步回调,这样是其最被广为使用的原因。
    下面将沿用“中国好室友” 来对回调方法做异步实现。
    回调接口不用变
    public interface DoHomeWork {
    void doHomeWork(String question, String answer);
    }
    为了体现异步的意思,我们给好室友设置了个较难的问题,希望好室友能多好点时间思考。
    Student student = new Student();
    String homework = "当x趋向于0,sin(x)/x =?";

    \r\n

    给学生新建个ask方法,该方法中另开一个线程,来等待回调方法的结果反馈。

    \r\n

    student.ask(homework, new RoomMate());

    \r\n

    ask方法如下

    \r\n

    public void ask(final String homework, final RoomMate roomMate) {
    new Thread(new Runnable() {

    \r\n
            @Override\r\n        public void run() {\r\n            roomMate.getAnswer(homework, Student.this);\r\n        }\r\n    }).start();\r\n\r\n    goHome();\r\n}
    \r\n

    新开的线程纯粹用来等待好室友来写完作用。由于在好室友类中设置了3秒的等待时间,所以可以看到goHome方法将先执行。

    \r\n

    意味着该学生在告知好室友做作用后,就可以做自己的事情去了,不需要同步阻塞去等待结果。

    \r\n

    一旦好室友完成作用,写入作业本,该现场也就结束运行了。

    \r\n

    完整代码
    public class Student implements DoHomeWork{

    \r\n

    @Override
    public void doHomeWork(String question, String answer) {
    System.out.println("作业本");
    if(answer != null) {
    System.out.println("作业:"+question+" 答案:"+ answer);
    } else {
    System.out.println("作业:"+question+" 答案:"+ "(空白)");
    }
    }

    \r\n

    public void ask(final String homework, final RoomMate roomMate) {
    new Thread(new Runnable() {

    \r\n
        @Override\r\n    public void run() {\r\n        roomMate.getAnswer(homework, Student.this);\r\n    }\r\n}).start();\r\n\r\ngoHome();
    \r\n

    }

    \r\n

    public void goHome(){
    System.out.println("我回家了……好室友,帮我写下作业。");
    }

    \r\n

    public static void main(String[] args) {
    Student student = new Student();
    String homework = "当x趋向于0,sin(x)/x =?";
    student.ask(homework, new RoomMate());

    \r\n

    }
    }
    public class RoomMate {

    \r\n
    public void getAnswer(String homework, DoHomeWork someone) {\r\n    if ("1+1=?".equals(homework)) {\r\n        someone.doHomeWork(homework, "2");\r\n    } else if("当x趋向于0,sin(x)/x =?".equals(homework)) {\r\n\r\n        System.out.print("思考:");\r\n        for(int i=1; i<=3; i++) {\r\n            System.out.print(i+"秒 ");\r\n            try {\r\n                TimeUnit.SECONDS.sleep(1);\r\n            } catch (InterruptedException e) {\r\n                e.printStackTrace();\r\n            }\r\n        }\r\n        System.out.println();\r\n        someone.doHomeWork(homework, "1");\r\n    } else {\r\n        someone.doHomeWork(homework, "(空白)");\r\n    }\r\n}
    \r\n

    }
    完结
    至此回调方法的介绍告一段落。

    \r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6781, 'e-commerce-platform-to-store-the-security-code-of-the-actual-demand-solutions', '电商平台实战之门店防伪码需求解决方案', '2015-01-27 02:54:27', '2019-03-26 00:05:22', '
    福利\r\n====\r\n照例,先来点福利解解乏~~\r\n\r\n\r\n需求概述\r\n========\r\n\r\n1、该项目有pc端、微信端、APP,需要做三套界面\r\n2、一辆汽车就是一个移动仓库,一个移动仓库可以对应多个区,移动仓库就是我们系统的门店。\r\n3、货品防伪码功能。每个货品(每瓶酒)都有单独的防伪码,每天要给不同的车分配防伪码。所以要有货品防伪码表和门店防伪码表。根据门店防伪码表就可以统计门店的货品库存。\r\n4、客户下单的时候,根据收货地址的所在区,判断该区对应的配送车是否有库存,库存充足则分配到该车负责配送,库存不足则由总店直接配送。\r\n5、移动仓库管理员通过微门店系统可以接受、发货签收订单。\r\n5、APP要有社区论坛功能,后台要有配置APP首页的广告图功能。\r\n\r\n我负责的任务概述\r\n================\r\n\r\n1、门店防伪码单独分配和批量导入及管理\r\n2、订单流程改造\r\n3、微门店改造\r\n\r\n我的分析与解决方案\r\n==================\r\n\r\n在目前的电商系统中,有这样的对应关系。\r\n1、一个商品对应对个货品,一个货品对应对个防伪码。\r\n2、一个商品(具体到货品)可以在多个门店售卖。\r\n3、一个门店可以对应多个区。\r\n\r\n因此,需要考虑一下流程:\r\n需要的表结构\r\nZtdArea\r\n\r\n```sql\r\n/****** Object:  Table [dbo].[ZtdArea]    Script Date: 01/27/2015 11:10:07 ******/\r\nSET ANSI_NULLS ON\r\nGO\r\n\r\nSET QUOTED_IDENTIFIER ON\r\nGO\r\n\r\nSET ANSI_PADDING ON\r\nGO\r\n\r\nCREATE TABLE [dbo].[ZtdArea](\r\n    [ZtdAreaID] [int] IDENTITY(1,1) NOT NULL,\r\n    [ztdno] [varchar](20) NOT NULL,\r\n    [county] [int] NULL,\r\n CONSTRAINT [PK_ZtdArea] PRIMARY KEY CLUSTERED\r\n(\r\n    [ZtdAreaID] ASC\r\n)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]\r\n) ON [PRIMARY]\r\n\r\nGO\r\n\r\nSET ANSI_PADDING OFF\r\nGO\r\n\r\nEXEC sys.sp_addextendedproperty @name=N\'MS_Description\', @value=N\'自增ID\' , @level0type=N\'SCHEMA\',@level0name=N\'dbo\', @level1type=N\'TABLE\',@level1name=N\'ZtdArea\', @level2type=N\'COLUMN\',@level2name=N\'ZtdAreaID\'\r\nGO\r\n\r\nEXEC sys.sp_addextendedproperty @name=N\'MS_Description\', @value=N\'门店编号\' , @level0type=N\'SCHEMA\',@level0name=N\'dbo\', @level1type=N\'TABLE\',@level1name=N\'ZtdArea\', @level2type=N\'COLUMN\',@level2name=N\'ztdno\'\r\nGO\r\n\r\nEXEC sys.sp_addextendedproperty @name=N\'MS_Description\', @value=N\'区行政编码\' , @level0type=N\'SCHEMA\',@level0name=N\'dbo\', @level1type=N\'TABLE\',@level1name=N\'ZtdArea\', @level2type=N\'COLUMN\',@level2name=N\'county\'\r\nGO\r\n```\r\n1、需要先录入货品防伪码,在录入门店防伪码,具体的可以在数据库判断\r\n转载请注明:特维博客 » 电商平台实战之门店防伪码需求解决方案\r\n\r\n未完待续
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6787, 'understanding-sql-server-keyword-nolock', '深入理解SQL Server之nolock关键字', '2015-01-29 02:27:57', '2019-03-25 21:29:22', '

    概念介绍

    \r\n开发人员喜欢在SQL脚本中使用WITH(NOLOCK), WITH(NOLOCK)其实是表提示(table_hint)中的一种。它等同于 READUNCOMMITTED 。 具体的功能作用如下所示(摘自MSDN):\r\n\r\n1: 指定允许脏读。不发布共享锁来阻止其他事务修改当前事务读取的数据,其他事务设置的排他锁不会阻碍当前事务读取锁定数据。允许脏读可能产生较多的并发操作,但其代价是读取以后会被其他事务回滚的数据修改。这可能会使您的事务出错,向用户显示从未提交过的数据,或者导致用户两次看到记录(或根本看不到记录)。有关脏读、不可重复读和幻读的详细信息,请参阅并发影响。\r\n\r\n2: READUNCOMMITTED 和 NOLOCK 提示仅适用于数据锁。所有查询(包括那些带有 READUNCOMMITTED 和 NOLOCK 提示的查询)都会在编译和执行过程中获取 Sch-S(架构稳定性)锁。因此,当并发事务持有表的 Sch-M(架构修改)锁时,将阻塞查询。例如,数据定义语言 (DDL) 操作在修改表的架构信息之前获取 Sch-M 锁。所有并发查询(包括那些使用 READUNCOMMITTED 或 NOLOCK 提示运行的查询)都会在尝试获取 Sch-S 锁时被阻塞。相反,持有 Sch-S 锁的查询将阻塞尝试获取 Sch-M 锁的并发事务。有关锁行为的详细信息,请参阅锁兼容性(数据库引擎)。\r\n\r\n3: 不能为通过插入、更新或删除操作修改过的表指定 READUNCOMMITTED 和 NOLOCK。SQL Server 查询优化器忽略 FROM 子句中应用于 UPDATE 或 DELETE 语句的目标表的 READUNCOMMITTED 和 NOLOCK 提示。\r\n

    功能与缺陷

    \r\n使用WIHT(NOLOCK)有利也有弊,所以在决定使用之前,你一定需要了解清楚WITH(NOLOCK)的功能和缺陷,看其是否适合你的业务需求,不要觉得它能提升性能,稀里糊涂的就使用它。\r\n
    1:使用WITH(NOLOCK)时查询不受其它排他锁阻塞\r\n\r\n打开会话窗口1,执行下面脚本,不提交也不回滚事务,模拟事务真在执行过程当中
    \r\n
    BEGIN TRAN\r\n    UPDATE TEST SET NAME=\'Timmy\' WHERE OBJECT_ID =1;\r\n--ROLLBACK
    \r\n打开会话窗口2,执行下面脚本,你会发现执行结果一直查询不出来(其实才两条记录)。当前会话被阻塞了\r\nsql SELECT * FROM TEST; 打开会话窗口3,执行下面脚本,查看阻塞情况,你会发现在会话2被会话1给阻塞了,会话2的等待类型为LCK_M_S:“当某任务正在等待获取共享锁时出现”\r\n
    \r\n\r\n  SELECT wt.blocking_session_id                    AS BlockingSessesionId\r\n        ,sp.program_name                           AS ProgramName\r\n        ,COALESCE(sp.LOGINAME, sp.nt_username)     AS HostName\r\n        ,ec1.client_net_address                    AS ClientIpAddress\r\n        ,db.name                                   AS DatabaseName\r\n        ,wt.wait_type                              AS WaitType\r\n        ,ec1.connect_time                          AS BlockingStartTime\r\n        ,wt.WAIT_DURATION_MS/1000                  AS WaitDuration\r\n        ,ec1.session_id                            AS BlockedSessionId\r\n        ,h1.TEXT                                   AS BlockedSQLText\r\n        ,h2.TEXT                                   AS BlockingSQLText\r\n  FROM sys.dm_tran_locks AS tl\r\n  INNER JOIN sys.databases db\r\n    ON db.database_id = tl.resource_database_id\r\n  INNER JOIN sys.dm_os_waiting_tasks AS wt\r\n    ON tl.lock_owner_address = wt.resource_address\r\n  INNER JOIN sys.dm_exec_connections ec1\r\n    ON ec1.session_id = tl.request_session_id\r\n  INNER JOIN sys.dm_exec_connections ec2\r\n    ON ec2.session_id = wt.blocking_session_id\r\n  LEFT OUTER JOIN master.dbo.sysprocesses sp\r\n    ON SP.spid = wt.blocking_session_id\r\n  CROSS APPLY sys.dm_exec_sql_text(ec1.most_recent_sql_handle) AS h1\r\n  CROSS APPLY sys.dm_exec_sql_text(ec2.most_recent_sql_handle) AS h2
    \r\n

    \r\n

    此时查看会话1(会话1的会话ID为53,执行脚本1前,可以用SELECT  @@spid查看会话ID)的锁信息情况,你会发现表TEST(ObjId=1893581784)持有的锁信息如下所示

    \r\n

    \r\n

       

    \r\n

    打开会话窗口4,执行下面脚本.你会发现查询结果很快就出来,会话4并不会被会话1阻塞。

    \r\n

        SELECT * FROM TEST WITH(NOLOCK)

    \r\n

    从上面模拟的这个小例子可以看出,正是由于加上WITH(NOLOCK)提示后,会话1中事务设置的排他锁不会阻碍当前事务读取锁定数据,所以会话4不会被阻塞,从而提升并发时查询性能。

    \r\n

    2:WITH(NOLOCK) 不发布共享锁来阻止其他事务修改当前事务读取的数据,这个就不举例子了。

    \r\n

    本质上WITH(NOLOCK)是通过减少锁和不受排它锁影响来减少阻塞,从而提高并发时的性能。所谓凡事有利也有弊,WITH(NOLOCK)在提升性能的同时,也会产生脏读现象。

    \r\n

    如下所示,表TEST有两条记录,我准备更新OBJECT_ID=1的记录,此时事务既没有提交也没有回滚

    \r\n

    \"clipboard[2]\"

    \r\n\r\n
    \r\n
    \r\n
    BEGIN TRAN
    \r\n
    \r\n
    UPDATE TEST SET NAME=\'Timmy\' WHERE OBJECT_ID =1;
    \r\n
    \r\n
    --ROLLBACK
    \r\n
    \r\n \r\n\r\n
    \r\n \r\n

    此时另外一个会话使用WITH(NOLOCK)查到的记录为未提交的记录值

    \r\n \r\n

    \"clipboard[3]\"

    \r\n \r\n

    假如由于某种原因,该事务回滚了,那么我们读取到的OBJECT_ID=1的记录就是一条脏数据。

    \r\n \r\n

    脏读又称无效数据的读出,是指在数据库访问中,事务T1将某一值修改,然后事务T2读取该值,此后T1因为某种原因撤销对该值的修改,这就导致了T2所读取到的数据是无效的。

    \r\n \r\n

    \r\n \r\n

    WITH(NOLOCK)使用场景

    \r\n \r\n

    \r\n \r\n

    什么时候可以使用WITH(NOLOCK)? 什么时候不能使用WITH(NOLOCK),这个要视你系统业务情况,综合考虑性能情况与业务要求来决定是否使用WITH(NOLOCK), 例如涉及到金融或会计成本之类的系统,出现脏读那是要产生严重问题的。关键业务系统也要慎重考虑。大体来说一般有下面一些场景可以使用WITH(NOLOCK)

    \r\n \r\n

       1: 基础数据表,这些表的数据很少变更。

    \r\n \r\n

       2:历史数据表,这些表的数据很少变更。

    \r\n \r\n

       3:业务允许脏读情况出现涉及的表。

    \r\n \r\n

       4:数据量超大的表,出于性能考虑,而允许脏读。

    \r\n \r\n

    另外一点就是不要滥用WITH(NOLOCK),我发现有个奇怪现象,很多开发知道WITH(NOLOCK),但是有不了解脏读,习惯性的使用WITH(NOLOCK)。

    \r\n \r\n

    \r\n \r\n

    WITH(NOLOCK)与 NOLOCK区别

    \r\n \r\n

    \r\n \r\n

    为了搞清楚WITH(NOLOCK)与NOLOCK的区别,我查了大量的资料,我们先看看下面三个SQL语句有啥区别

    \r\n \r\n

        SELECT * FROM TEST NOLOCK

    \r\n \r\n

        SELECT * FROM TEST (NOLOCK);

    \r\n \r\n

        SELECT * FROM TEST WITH(NOLOCK);

    \r\n \r\n

    上面的问题概括起来也就是说NOLOCK、(NOLOCK)、 WITH(NOLOCK)的区别:

    \r\n \r\n

    1: NOLOCK这样的写法,其实NOLOCK其实只是别名的作用,而没有任何实质作用。所以不要粗心将(NOLOCK)写成NOLOCK

    \r\n \r\n

    2:(NOLOCK)与WITH(NOLOCK)其实功能上是一样的。(NOLOCK)只是WITH(NOLOCK)的别名,但是在SQL Server 2008及以后版本中,(NOLOCK)不推荐使用了,\"不借助 WITH 关键字指定表提示”的写法已经过时了。 具体参见MSDN http://msdn.microsoft.com/zh-cn/library/ms143729%28SQL.100%29.aspx

    \r\n \r\n

        2.1  至于网上说WITH(NOLOCK)在SQL SERVER 2000不生效,我验证后发现完全是个谬论。

    \r\n \r\n

        2.2  在使用链接服务器的SQL当中,(NOLOCK)不会生效,WITH(NOLOCK)才会生效。如下所示

    \r\n \r\n

    \"clipboard[4]\"

    \r\n \r\n

        消息 4122,级别 16,状态 1,第 1 行

    \r\n \r\n

        Remote table-valued function calls are not allowed.

    \r\n \r\n

    \r\n \r\n

    WITH(NOLOCK)会不会产生锁

    \r\n \r\n

        很多人误以为使用了WITH(NOLOCK)后,数据库库不会产生任何锁。实质上,使用了WITH(NOLOCK)后,数据库依然对该表对象生成Sch-S(架构稳定性)锁以及DB类型的共享锁, 如下所示,可以在一个会话中查询一个大表,然后在另外一个会话中查看锁信息(也可以使用SQL Profile查看会话锁信息)

    \r\n \r\n

        不使用WTIH(NOLOCK)

    \r\n \r\n

    \"clipboard[5]\"

    \r\n \r\n

      使用WITH(NOLOCK)

    \r\n \r\n

    \"clipboard[6]\"

    \r\n \r\n

      从上可以看出使用WITH(NOLOCK)后,数据库并不是不生成相关锁。  对比可以发现使用WITH(NOLOCK)后,数据库只会生成DB类型的共享锁、以及TAB类型的架构稳定性锁.

    \r\n \r\n

    另外,使用WITH(NOLOCK)并不是说就不会被其它会话阻塞,依然可能会产生Schema Change Blocking

    \r\n \r\n

    会话1:执行下面SQL语句,暂时不提交,模拟事务正在执行

    \r\n \r\n
    \r\n
    \r\n
    BEGIN TRAN
    \r\n
    \r\n
      ALTER TABLE TEST ADD Grade VARCHAR(10) ;
    \r\n
    \r\n \r\n\r\n
    \r\n \r\n

    会话2:执行下面语句,你会发现会话被阻塞,截图如下所示。

    \r\n \r\n
    \r\n
    \r\n
    SELECT * FROM TEST WITH(NOLOCK)
    \r\n
    \r\n
    \r\n

    \"image\"

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6794, '6794', '', '2015-01-29 02:42:16', '2019-03-26 00:04:47', '

    \"clipboard\"

    \r\n

    \r\n

    此时查看会话1(会话1的会话ID为53,执行脚本1前,可以用SELECT  @@spid查看会话ID)的锁信息情况,你会发现表TEST(ObjId=1893581784)持有的锁信息如下所示

    \r\n

    \r\n

    \"clipboard[1]\"

    \r\n

       

    \r\n

    打开会话窗口4,执行下面脚本.你会发现查询结果很快就出来,会话4并不会被会话1阻塞。

    \r\n

        SELECT * FROM TEST WITH(NOLOCK)

    \r\n

    从上面模拟的这个小例子可以看出,正是由于加上WITH(NOLOCK)提示后,会话1中事务设置的排他锁不会阻碍当前事务读取锁定数据,所以会话4不会被阻塞,从而提升并发时查询性能。

    \r\n

    \r\n

    2:WITH(NOLOCK) 不发布共享锁来阻止其他事务修改当前事务读取的数据,这个就不举例子了。

    \r\n

    本质上WITH(NOLOCK)是通过减少锁和不受排它锁影响来减少阻塞,从而提高并发时的性能。所谓凡事有利也有弊,WITH(NOLOCK)在提升性能的同时,也会产生脏读现象。

    \r\n

    如下所示,表TEST有两条记录,我准备更新OBJECT_ID=1的记录,此时事务既没有提交也没有回滚

    \r\n

    \"clipboard[2]\"

    \r\n\r\n
    \r\n
    \r\n
    BEGIN TRAN
    \r\n
    \r\n
    UPDATE TEST SET NAME=\'Timmy\' WHERE OBJECT_ID =1;
    \r\n
    \r\n
    --ROLLBACK
    \r\n
    \r\n
    \r\n
    \r\n

    此时另外一个会话使用WITH(NOLOCK)查到的记录为未提交的记录值

    \r\n

    \"clipboard[3]\"

    \r\n

    假如由于某种原因,该事务回滚了,那么我们读取到的OBJECT_ID=1的记录就是一条脏数据。

    \r\n

    脏读又称无效数据的读出,是指在数据库访问中,事务T1将某一值修改,然后事务T2读取该值,此后T1因为某种原因撤销对该值的修改,这就导致了T2所读取到的数据是无效的。

    \r\n

    \r\n

    WITH(NOLOCK)使用场景

    \r\n

    \r\n

    什么时候可以使用WITH(NOLOCK)? 什么时候不能使用WITH(NOLOCK),这个要视你系统业务情况,综合考虑性能情况与业务要求来决定是否使用WITH(NOLOCK), 例如涉及到金融或会计成本之类的系统,出现脏读那是要产生严重问题的。关键业务系统也要慎重考虑。大体来说一般有下面一些场景可以使用WITH(NOLOCK)

    \r\n

       1: 基础数据表,这些表的数据很少变更。

    \r\n

       2:历史数据表,这些表的数据很少变更。

    \r\n

       3:业务允许脏读情况出现涉及的表。

    \r\n

       4:数据量超大的表,出于性能考虑,而允许脏读。

    \r\n

    另外一点就是不要滥用WITH(NOLOCK),我发现有个奇怪现象,很多开发知道WITH(NOLOCK),但是有不了解脏读,习惯性的使用WITH(NOLOCK)。

    \r\n

    \r\n

    WITH(NOLOCK)与 NOLOCK区别

    \r\n

    \r\n

    为了搞清楚WITH(NOLOCK)与NOLOCK的区别,我查了大量的资料,我们先看看下面三个SQL语句有啥区别

    \r\n

        SELECT * FROM TEST NOLOCK

    \r\n

        SELECT * FROM TEST (NOLOCK);

    \r\n

        SELECT * FROM TEST WITH(NOLOCK);

    \r\n

    上面的问题概括起来也就是说NOLOCK、(NOLOCK)、 WITH(NOLOCK)的区别:

    \r\n

    1: NOLOCK这样的写法,其实NOLOCK其实只是别名的作用,而没有任何实质作用。所以不要粗心将(NOLOCK)写成NOLOCK

    \r\n

    2:(NOLOCK)与WITH(NOLOCK)其实功能上是一样的。(NOLOCK)只是WITH(NOLOCK)的别名,但是在SQL Server 2008及以后版本中,(NOLOCK)不推荐使用了,\"不借助 WITH 关键字指定表提示”的写法已经过时了。 具体参见MSDN http://msdn.microsoft.com/zh-cn/library/ms143729%28SQL.100%29.aspx

    \r\n

        2.1  至于网上说WITH(NOLOCK)在SQL SERVER 2000不生效,我验证后发现完全是个谬论。

    \r\n

        2.2  在使用链接服务器的SQL当中,(NOLOCK)不会生效,WITH(NOLOCK)才会生效。如下所示

    \r\n

    \"clipboard[4]\"

    \r\n

        消息 4122,级别 16,状态 1,第 1 行

    \r\n

        Remote table-valued function calls are not allowed.

    \r\n

    \r\n

    WITH(NOLOCK)会不会产生锁

    \r\n

        很多人误以为使用了WITH(NOLOCK)后,数据库库不会产生任何锁。实质上,使用了WITH(NOLOCK)后,数据库依然对该表对象生成Sch-S(架构稳定性)锁以及DB类型的共享锁, 如下所示,可以在一个会话中查询一个大表,然后在另外一个会话中查看锁信息(也可以使用SQL Profile查看会话锁信息)

    \r\n

        不使用WTIH(NOLOCK)

    \r\n

    \"clipboard[5]\"

    \r\n

      使用WITH(NOLOCK)

    \r\n

    \"clipboard[6]\"

    \r\n

      从上可以看出使用WITH(NOLOCK)后,数据库并不是不生成相关锁。  对比可以发现使用WITH(NOLOCK)后,数据库只会生成DB类型的共享锁、以及TAB类型的架构稳定性锁.

    \r\n

    另外,使用WITH(NOLOCK)并不是说就不会被其它会话阻塞,依然可能会产生Schema Change Blocking

    \r\n

    会话1:执行下面SQL语句,暂时不提交,模拟事务正在执行

    \r\n\r\n
    \r\n
    \r\n
    BEGIN TRAN
    \r\n
    \r\n
      ALTER TABLE TEST ADD Grade VARCHAR(10) ;
    \r\n
    \r\n
    \r\n
    \r\n

    会话2:执行下面语句,你会发现会话被阻塞,截图如下所示。

    \r\n\r\n
    \r\n
    \r\n
    SELECT * FROM TEST WITH(NOLOCK)
    \r\n
    \r\n
    \r\n

    \"image\"

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6796, 'the-command-line-windows-study-notes-001-cmd-script-that-receives-user-input-information', 'Windows脚本学习笔记001:CMD命令行接收用户输入信息', '2015-01-29 06:16:13', '2019-03-26 00:04:39', '

    前言

    \r\n

    一直以来都用centos的curl命令,今天在windows上使用,感觉脚本比写程序有时候还是快很多,因此,抽时间学习一下bat脚本,感觉用C#或Java有时候还是不够简洁。

    \r\n

    未完待续

    \r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6803, 'current-java-project-in-the-development-of-several-misunderstandings', 'aaa', '2015-01-31 08:17:04', '2019-03-25 21:29:22', '
    本文转载自互联网,仅供学习和参考。\r\n\r\n软件的生命性\r\n============\r\n\r\n软件是有生命的,这可能是老调重弹了,但是因为它事关分层架构的原由,反复强调都不过分。\r\n\r\n一个有生命的软件首先必须有一个灵活可扩展的基础架构,其次才是完整的功能。\r\n\r\n目前很多人对软件的思想还是焦点落在后者:完整的功能,觉得一个软件功能越完整越好,其实关键还是架构的灵活性,就是前者,基础架构好,功能添加只是时间和工作量问题,但是如果架构不好,功能再完整,也不可能包括未来所有功能,软件是有生命的,在未来成长时,更多功能需要加入,但是因为基础架构不灵活不能方便加入,死路一条。\r\n\r\n正因为普通人对软件存在短视误区,对功能追求高于基础架构,很多吃了亏的老程序员就此离开软件行业,带走宝贵的失败经验,新的盲目的年轻程序员还是使用老的思维往前冲。其实很多国外免费开源框架如ofbiz compiere和slide也存在这方面陷阱,貌似非常符合胃口,其实类似国内那些几百元的盗版软件,扩展性以及持续发展性严重不足。\r\n\r\n那么选择现在一些流行的框架如Hibernate、Spring/Jdonframework是否就表示基础架构打好了呢?其实还不尽然,关键还是取决于你如何使用这些框架来搭建你的业务系统。\r\n\r\n存储过程和复杂SQL语句的陷阱\r\n===========================\r\n\r\n首先谈谈存储过程使用的误区,使用存储过程架构的人以为可以解决性能问题,其实它正是导致性能问题的罪魁祸首之一,打个比喻:如果一个人频临死亡,打一针可以让其延长半年,但是打了这针,其他所有医疗方案就全部失效,请问你会使用这种短视方案吗?\r\n\r\n为什么这样说呢?如果存储过程都封装了业务过程,那么运行负载都集中在数据库端,要中间J2EE应用服务器干什么?要中间服务器的分布式计算和集群能力做什么?只能回到过去集中式数据库主机时代。现在软件都是面向互联网的,不象过去那样局限在一个小局域网,多用户并发访问量都是无法确定和衡量,依靠一台数据库主机显然是不能够承受这样恶劣的用户访问环境的。(当然搞数据库集群也只是五十步和百步的区别)。\r\n\r\n从分层角度来看,现在三层架构:表现层、业务层和持久层,三个层次应该分割明显,职责分明:持久层职责持久化保存业务模型对象,业务层对持久层的调用只是帮助我们激活曾经委托其保管的对象,所以,不能因为持久层是保管者,我们就以其为核心围绕其编程,除了要求其归还模型对象外,还要求其做其做复杂的业务组合。打个比喻:你在火车站将水果和盘子两个对象委托保管处保管,过了两天来取时,你还要求保管处将水果去皮切成块,放在盘子里,做成水果盘给你,合理吗?\r\n\r\n上面是谈过分依赖持久层的一个现象,还有一个正好相反现象,持久层散发出来,开始挤占业务层,腐蚀业务层,整个业务层到处看见的是数据表的影子(包括数据表的字段),而不是业务对象。这样程序员应该多看看[OO经典PoEAA](http://www.martinfowler.com/eaaCatalog/index.html)。[PoEAA](http://www.martinfowler.com/eaaCatalog/index.html)?认为除了持久层,不应该在其他地方看到数据表或表字段名。\r\n\r\n当然适量使用存储过程,使用数据库优点也是允许的。按照Evans DDD理论,可以将SQL语句和存储过程作为规则Specification一部分。\r\n\r\nHibernate等ORM问题\r\n==================\r\n\r\n 现在使用Hibernate人也不少,但是他们发现Hibernate性能缓慢,所以寻求解决方案,其实并不是 Hibernate性能缓慢,而是我们使用方式发生错误:\r\n\r\n“最近本人正搞一个项目,项目中我们用到了struts1.2+hibernate3, 由于关系复杂表和表之间的关系很多,在很多地方把lazy都设置false,所以导致数据一加载很慢,而且查询一条数据更是非常的慢。”\r\n\r\nHibernate是一个基于对象模型持久化的技术,因此,关键是我们需要设计出高质量的对象模型,遵循DDD领域建模原则,减少降低关联,通过分层等有效办法处理关联。如果采取围绕数据表进行设计编程,加上表之间关系复杂(没有科学方法处理、侦察或减少这些关系),必然导致 系统运行缓慢,其实同样问题也适用于当初对EJB的实体Bean的CMP抱怨上,实体Bean是Domain Model持久化,如果不首先设计Domain Model,而是设计数据表,和持久化工具设计目标背道而驰,能不出问题吗?关于这个问题N多年就在Jdon争论过。\r\n\r\n这里同样延伸出另外一个问题:数据库设计问题,数据库是否需要在项目开始设计?\r\n 如果我们进行数据库设计,那么就产生了一系列问题:当我们使用Hibernate实现持久保存时,必须考虑事先设计好的数据库表结构以及他们的关系如何和业务对象实现映射,这实际上是非常难实现的,这也是很多人觉得使用ORM框架棘手根本原因所在。\r\n\r\n当然,也有脑力相当发达的人可以 实现,但是这种围绕数据库实现映射的结果必然扭曲业务对象,这类似于两个板块(数据表和业务对象)相撞,必然产生地震,地震的结果是两败俱伤, 软的一方吃亏,业务对象是代码,相当于数据表结构,属于软的一方,最后导致业务对象变成数据传输对象DTO, DTO满天飞,性能和维护问题随之而来。\r\n\r\n领域建模解决了上述众多不协调问题,特别是ORM痛苦使用问题,关于ORM/Hibernate使用还是那句老话:如果你不掌握领域建模方法,那么就不要用Hibernate,对于这个层次的你:也许No ORM 更是一个简单之道: No ORM: The simplest solution\r\n\r\n\r\nSpring分层矛盾问题\r\n==================\r\n\r\n Spring是以挑战EJB面貌出现,其本身拥有的强大组件定制功能是优点,但是存在实战的一些问题,Spring作为业务层框架,不支持业务层Session 功能。\r\n\r\n具体举例如下:当我们实现购物车之类业务功能时,需要将购物场合保存到Session中,由于业务层没有方便的Session支持,我们只得将购物车保存到 HttpSession,而HttpSession只有通过HttpRequest才能获得,再因为在Spring业务层容器中是无法访问到HttpRequest这个对象的,所以, 最后我们只能将“购物车保存到HttpSession”这个功能放在表现层中实现,而这个功能明显应该属于业务层功能,这就导致我们的Java项目层次混乱,维护性差。 违背了使用Spring和分层架构最初目的。\r\n\r\n相关案例:请教一个在完整提交前临时保存的问题:\r\n\r\n\r\n领域驱动设计DDD\r\n===============\r\n\r\n 现在回到我们讨论的重点上来,分层架构是我们使用Java的根本原因之一,域建模专家Eric Evans在他的“Domain Model Design”一书中开篇首先强调的是分层架构,整个DDD理论实际是告诉我们如何使用模型对象oo技术和分层架构来设计实现一个Java项目。\r\n\r\n我们现在很多人知道Java项目基本有三层:表现层 业务层和持久层,当我们执著于讨论各层框架如何选择之时,实际上我们真正的项目开发工作还没有开始, 就是我们选定了某种框架的组合(如Struts+Spring+Hibernate或Struts+EJB或Struts+JdonFramework),我们还没有意识到业务层工作还需要大量工作,DDD提供了在业务层中再划分新的层次思想,如领域层和服务层,甚至再细分为作业层、能力层、策略层等等。通过层次细化方式达到复杂软件的松耦合。DDD提供了如何细分层次的方式\r\n\r\n当我们将精力花费在架构技术层面的讨论和研究上时,我们可能忘记以何种依据选择这些架构技术?选择标准是什么?领域驱动设计DDD 回答了这样的问题,DDD会告诉你如果一个框架不能协助你实现分层架构,那就抛弃它,同时,DDD也指出选择框架的考虑目的,使得你不会 人云亦云,陷入复杂的技术细节迷雾中,迷失了架构选择的根本方向。\r\n\r\n现在也有些人误以为DDD是一种新的理论,其实DDD和设计模式一样,不是一种新的理论,而是实战经验的总结,它将前人 使用面向模型设计的方法经验提炼出来,供后来者学习,以便迅速找到驾驭我们软件项目的根本之道。\r\n\r\n现在Evans DDD概念很火,因为它将著名的[PoEAA](http://www.martinfowler.com/eaaCatalog/index.html)进行了具化,实现了[PoEAA](http://www.martinfowler.com/eaaCatalog/index.html)可操作性,这也是MF大力推崇的原因。最近(8月8日)一位老外博客上用微软的.NET架构和Evans DDD比较的文章:,这篇文章比较了微软的三层服务应用架构[Microsoft TLSA]和Evans DDD的架构, 使用Microsoft .NET Pet Shop 4为例子,解释两个目标的区别,并且表明\r\n 微软是如何在案例中更好地实现支持后者。这篇文章帮助哪些.NET平台上有域设计知识的人实现更好地提高。\r\n
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6809, 'address-the-fetching-android-sdk-problem-loads-component-information-for-too-long', 'Android Studio解决Fetching android sdk component information加载过久问题', '2015-01-31 16:03:42', '2019-03-25 21:29:22', '

    安装完成后,如果直接启动,Android Studio会去获取 android sdk 组件信息,这个过程相当慢,还经常加载失败,导致Android Studio启动不起开。解决办法就是不去获取android sdk 组件信息。方法如下:

    \r\n

    1)进入刚安装的Android Studio目录下的bin目录。找到idea.properties文件,用文本编辑器打开。

    \r\n

    2)在idea.properties文件末尾添加一行:

    \r\n
        disable.android.first.run=true
    \r\n

    ,然后保存文件。

    \r\n

    3)关闭Android Studio后重新启动,便可进入界面。

    \r\n

    \r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6823, 'spring-mvc-uses-autowired-a-simple-implementation-of-dependency-injection', 'Spring MVC利用@Autowired注解简单实现依赖注入', '2015-02-01 13:55:57', '2019-03-26 00:04:06', '我们编写spring 框架的代码时候。一直遵循是这样一个规则:所有在spring中注入的bean 都建议定义成私有的域变量。并且要配套写上\r\nget 和 set方法。\r\n\r\n```java \r\nprivate VideoService videoService; \r\n\r\npublic VideoService getVideoService() { \r\n return videoService;\r\n}\r\n \r\npublic void setVideoService(VideoService videoService) { \r\n this.videoService =videoService;\r\n} \r\n```\r\n\r\nxml里面需要这样\r\n\r\n```xml\r\n\r\n\r\n\r\n\r\n\r\n\r\n \r\n\r\n```\r\n\r\n如果用自动注入,只需要这样\r\n\r\n\r\n``` java\r\n//依赖注入\r\n@Autowired\r\nprivate VideoService videoService;\r\n```\r\n\r\nxml中\r\n\r\n```xml\r\n\r\n\r\n\r\n```\r\n\r\nVideoService定义\r\n\r\n```java\r\n/**\r\n* Created by 唐有炜 on 2015/2/1.\r\n*/\r\npublic interface VideoService {\r\n/**\r\n * 根据url获取可供播放的Video对象\r\n * @param url 要解析的网址\r\n * @return Video对象\r\n */\r\nVideo getVideoModel(String url);\r\n}\r\n```\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6828, 'sql-server-uses-common-errors', 'SQL Server使用常见误区', '2015-02-04 02:31:16', '2019-03-25 23:59:55', '
    情景重现\r\n========\r\n\r\n案例一\r\n------\r\n\r\n### IF没有添加BEGIN END,直接RETURN\r\n\r\n例如以下语句\r\n\r\n```sql\r\n...\r\nIF XXX2\r\ndo sth.\r\nRETURN\r\n...\r\n```\r\n\r\n这个语句看似简单,但是运行会发现,运行结果不是你预想的那样。\r\n\r\n本来我们的意图是想判断某一个条件,如果符合,就停止运行。\r\n\r\n但是执行之后你会发现,无论IF真假与否,RETURN都会执行。\r\n\r\n解决方案\r\n\r\n因此需要加上BEGIN END来控制。\r\n\r\n正确的写法\r\n\r\n```sql\r\n...\r\nIF XXX\r\n    BEGIN\r\n        do sth.\r\n        RETURN\r\n    END\r\n...\r\n```\r\n\r\n错误原因\r\n\r\n一般IF后面有很多语句时候,我们会记住用BEGIN END,但因为一条语句,可以忽略,有时候就忘了加。\r\n\r\n**因此,最好的办法是每一个IF后面都加上BEGIN END。**\r\n\r\n案例二\r\n------\r\n\r\n### 在事务未提交之前试图通过return回滚\r\n\r\n错误写法\r\n\r\n```sql\r\n...\r\nbegin transaction\r\n   IF XXX\r\n      BEGIN\r\n         do sth.\r\n      END\r\n   ELSE\r\n      BEGIN\r\n         RETURN--错误\r\n      END\r\nrollback\r\ncommit\r\n...\r\n```\r\n分析\r\n\r\n如果BEGIN一个TRAN以后直接RETURN,事务会不会回滚?\r\n\r\n开启了事务,必须在RETURN之前回滚或者提交事务, SQL SERVER不会自动帮你处理这个。\r\n\r\n正确写法\r\n\r\n```sql\r\n...\r\nbegin transaction\r\n   IF XXX\r\n      BEGIN\r\n         do sth.\r\n      END\r\n   ELSE\r\n   BEGIN\r\n      rollback\r\n   END\r\ncommit\r\n...\r\n```\r\n\r\n延伸\r\n\r\n在C#中,如果没有使用连接池,则事务在连接断开和销毁时被强制回滚,如果使用连接池,则事务在连接被再次使用时调用的exec sp_reset_connection存储过程清理掉。如果该连接没有被再次使用或删除,则事务一直存在,便会一直锁住相关资源不释放,照常日志变大,镜像和复制异常等情况。\r\n\r\n参考\r\n\r\nhttp://www.cnblogs.com/TeyGao/p/3522965.html\r\n\r\n未完待续\r\n\r\n文章来自笔者博客,使用Markdown编辑发布,原文地址:[SQL Server使用常见误区](http://www.terwer.com/sql-server-uses-common-errors.html)\r\n
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6840, 'win7-64-bit-install-oracle-10g-hint-has-to-be-51-is-actually-61-or-abnormal-program-termination-an-unknown-error-occurred-solutions', 'Win7 64位安装Oracle 10g 提示“必须是5.1 实际为6.1”或“程序异常终止,发生未知错误”的解决方法', '2015-02-06 12:58:32', '2019-03-25 21:29:22', '
    问题描述\r\n========\r\n\r\n我的Oracle 10g版本是10.2.0.1.0,(10.1同理)选择高级安装,提示“程序异常终止,发生未知错误”。\r\n\r\n![](http://bcs.duapp.com/terwer/blog/2015/02/2015-02-06_221519.png)\r\n\r\n解决方案\r\n========\r\n\r\n1.修改 ```oracle 10g\\database\\stage\\prereq\\db\\refhost.xml```\r\n\r\n当打开refhost.xml后会发现有\r\n\r\n```xml\r\n\r\n.....\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n```\r\n\r\n只要在 后面添加\r\n\r\n```xml\r\n\r\n\r\n\r\n\r\n\r\n```\r\n\r\n2.到install目录中找到oraparam.ini文件,把\r\n\r\n```ini\r\n#Windows=4.0,5.0,5.1,5.2\r\n```\r\n\r\n修改成\r\n```ini\r\n#Windows=4.0,5.0,5.1,5.2,6.1\r\n\'\'\'\r\n并在后面添加\r\n```ini\r\n[Windows-6.1-required]\r\n#Minimum display colours for OUI to run\r\nMIN_DISPLAY_COLORS=256\r\n#Minimum CPU speed required for OUI\r\n#CPU=300\r\n[Windows-6.1-optional]\r\n```\r\n\r\n3.右键setup.exe,属性->兼容性->以兼容模式运行这个程序 windows xp( service pack 3),以管理员身份运行安装就可以了。\r\n\r\n下载地址\r\n========\r\nOracle10g下载地址(多平台下的32位和64位)\r\n前段时间ORACLE把10G的下载从官网拿掉了 ,许多童鞋不知道ORACLE 10g 的下载地址,这里我附上oracle 10g 下载的链接,方便大家下载。\r\n点击链接使用迅雷即可下载。\r\n4种包的介绍:\r\n\r\n包名称|介绍\r\n---|---\r\n***_database_*.zip|oracle数据库 服务端 软件的安装包,如果你要创建一个数据库,请下载这个版本\r\n***_client_*.zip|是oracle数据库客户端软件的安装包,如果你不需要创建数据库,只是用来操作远程电脑上的数据库时,请下载这个版本\r\n***_gateways_*.zip|oracle透明网关,如果你要链接其他数据库,请下载这个软件包\r\n***_clusterware_*.zip|oracle集群软件,如果你要做RAC,请下载这个软件包\r\n\r\n## Oracle Database 10g Release 2 (10.2.0.1.0) Enterprise/Standard Edition for Linux x86\r\n\r\nhttp://download.oracle.com/otn/linux/oracle10g/10201/10201_database_linux32.zip\r\n\r\nhttp://download.oracle.com/otn/linux/oracle10g/10201/10201_client_linux32.zip\r\n\r\nhttp://download.oracle.com/otn/linux/oracle10g/10201/10201_clusterware_linux32.zip\r\n\r\nhttp://download.oracle.com/otn/linux/oracle10g/10201/10201_gateways_linux32.zip\r\n\r\n## Oracle Database 10g Release 2 (10.2.0.1.0) Enterprise/Standard Edition for Linux x86-64\r\n\r\nhttp://download.oracle.com/otn/linux/oracle10g/10201/10201_database_linux_x86_64.cpio.gz\r\n\r\nhttp://download.oracle.com/otn/linux/oracle10g/10201/10201_client_linux_x86_64.cpio.gz\r\n\r\nhttp://download.oracle.com/otn/linux/oracle10g/10201/10201_clusterware_linux_x86_64.cpio.gz\r\n\r\nhttp://download.oracle.com/otn/linux/oracle10g/10201/10201_gateways_linux_x86_64.cpio.gz\r\n\r\n## Oracle Database 10g Release 2 (10.2.0.1.0) Enterprise/Standard Edition for Microsoft Windows (32-bit)\r\n\r\nhttp://download.oracle.com/otn/nt/oracle10g/10201/10201_database_win32.zip\r\n\r\nhttp://download.oracle.com/otn/nt/oracle10g/10201/10201_client_win32.zip\r\n\r\nhttp://download.oracle.com/otn/nt/oracle10g/10201/10201_clusterware_win32.zip\r\n\r\nhttp://download.oracle.com/otn/nt/oracle10g/10201/10201_gateways_win32.zip\r\n\r\n## Oracle Database 10g Release 2 (10.2.0.1.0) Enterprise/Standard Edition for Microsoft Windows (x64)\r\n\r\nhttp://download.oracle.com/otn/nt/oracle10g/10201/102010_win64_x64_database.zip\r\n\r\nhttp://download.oracle.com/otn/nt/oracle10g/10201/102010_win64_x64_client.zip\r\n\r\nhttp://download.oracle.com/otn/nt/oracle10g/10201/102010_win64_x64_clusterware.zip\r\n\r\n如果是win7 64位,可能下载上面的版本还是无法安装,需要下载下面的这个版本:\r\n\r\nhttp://download.oracle.com/otn/nt/oracle10g/10204/10204_vista_w2k8_x64_production_db.zip\r\n\r\n## Oracle Database 10g Release 2 (10.2.0.1.0) Enterprise/Standard Edition for AIX5L\r\n\r\nhttp://download.oracle.com/otn/aix/oracle10g/10201/10gr2_aix5l64_database.cpio.gz\r\n\r\nhttp://download.oracle.com/otn/aix/oracle10g/10201/10gr2_aix5l64_client.cpio.gz\r\n\r\nhttp://download.oracle.com/otn/aix/oracle10g/10201/10gr2_aix5l64_cluster.cpio.gz\r\n\r\nhttp://download.oracle.com/otn/aix/oracle10g/10201/10gr2_aix5l64_gateways.cpio.gz\r\n\r\n## Oracle Database 10g Release 2 (10.2.0.2) Enterprise/Standard Edition for Solaris Operating System (x86)\r\n\r\nhttp://download.oracle.com/otn/solaris/oracle10g/10202/10202_database_solx86.zip\r\n\r\nhttp://download.oracle.com/otn/solaris/oracle10g/10202/10202_client_solx86.zip\r\n\r\nhttp://download.oracle.com/otn/solaris/oracle10g/10202/10202_clusterware_solx86.zip\r\n\r\n## Oracle Database 10g Release 2 (10.2.0.1.0) Enterprise/Standard Edition for Solaris Operating System (x86-64)\r\n\r\nhttp://download.oracle.com/otn/solaris/oracle10g/10201/x8664/10201_database_solx86_64.zip\r\n\r\nhttp://download.oracle.com/otn/solaris/oracle10g/10201/x8664/10201_client_solx86_64.zip\r\n\r\nhttp://download.oracle.com/otn/solaris/oracle10g/10201/x8664/10201_clusterware_solx86_64.zip \r\n\r\n参考\r\n====\r\nhttp://www.cnblogs.com/yuchuan/archive/2013/06/06/lyc.html \r\n\r\n
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6910, '20150208001546', '20150208001546', '2015-02-07 16:15:47', '2019-03-25 21:29:22', '再远的路,也要回到起点,从今天开始,继续回到梦开始的地方,重新转向Android开发。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6913, '20150208215818', '20150208215818', '2015-02-08 13:58:12', '2019-03-25 21:29:22', '转变学习方法,第一天看书,第二天实践。\r\n周末总结。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6914, '20150209000317', '20150209000317', '2015-02-08 16:03:13', '2019-03-25 21:29:22', 'java泛型使用擦除法实现,对比.net泛型。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6915, 'actual-store-inventory-allocation-strategy-of-e-commerce-platform', '电商平台实战之门店库存分配策略', '2015-02-10 04:11:48', '2019-03-25 23:58:07', '情景重现\r\n========\r\n## 客户需求\r\n客户为酒水供应商,每个地区安排车辆配送,同时每个地区都有对应门店,每天晚上会事先分配好库存。\r\n\r\n客户添加到购物车时,判断每一个货品对应的门店的库存情况。\r\n\r\n生成订单时,遍历门店,判断所有货品在门店的库存情况,全部货品均满足库存,则分配给该门店,否则,分配给总店。\r\n\r\n## 15-02-26 新增需求\r\n1、需要索取发票的订单,由总部统一分配。\r\n\r\n2、提交订单的时候匹配不到满足整单库存的该区域门店,此订单不分配门店,由总部统一分配。\r\n\r\n存储过程实现\r\n============\r\n```\r\n/*\r\nversion:v1.6\r\nauthor:tangyouwei\r\ntime:20150203\r\ncontent:\r\n1.删除参数ztdID,修改参数ztdNo为out,添加参数areaID,用于表示第三级地区,门店ID和编号通过地区分配\r\n*/\r\n--统计商品数量\r\nselect t.productid,t.goodsid,Quantity=sum(t.Quantity)\r\ninto #groupcart\r\nfrom #cart t(nolock)\r\ngroup by t.goodsid,t.productid\r\n--判断货品库存\r\nif exists(\r\nselect g.goodsid,g.Storage,g.LockStorage,(g.Storage-g.LockStorage) as cannum,t.Quantity,* from goods g,#groupcart t\r\nwhere g.goodsid=t.goodsid\r\nand (g.Storage-g.LockStorage)\r\n```', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6920, 'centos-modify-the-system-environment-variables', 'CentOS修改系统环境变量', '2015-02-11 07:43:49', '2019-03-25 21:29:22', '
    情景再现\r\n========\r\n我这里拿php作为一个例子,我的php安装在 ```/usr/local/webserver/php``` 下,没有把php加入环境变量时,你在命令行执行\r\n```sh\r\n#查看当前php的版本信息\r\n[root@CentOS ~]# php -v\r\n```\r\n会提示你此命令不存在。\r\n\r\nlinux下修改环境变量的方法\r\n=======================================\r\n\r\n方法一: 在/etc/profile文件中添加变量【对所有用户生效(永久的)】\r\n-------------------------------------------------------------------\r\n用VI在文件/etc/profile文件中增加变量,该变量将会对Linux下所有用户有效,并且是“永久的”。\r\n```sh\r\n[root@AY140529210959Z ~]# vi /etc/profile\r\n```\r\n在文件末尾加上如下两行代码\r\n```sh\r\nPATH=/usr/local/webserver/php/bin:$PATH\r\nexport PATH\r\n```\r\n\r\n```sh\r\n# /etc/profile\r\n\r\n# System wide environment and startup programs, for login setup\r\n# Functions and aliases go in /etc/bashrc\r\n\r\n# It\'s NOT a good idea to change this file unless you know what you\r\n# are doing. It\'s much better to create a custom.sh shell script in\r\n# /etc/profile.d/ to make custom changes to your environment, as this\r\n# will prevent the need for merging in future updates.\r\n\r\npathmunge () {\r\n    case \":${PATH}:\" in\r\n        *:\"$1\":*)\r\n            ;;\r\n        *)\r\n            if [ \"$2\" = \"after\" ] ; then\r\n                PATH=$PATH:$1\r\n            else\r\n                PATH=$1:$PATH\r\n            fi\r\n    esac\r\n}\r\n\r\n\r\nif [ -x /usr/bin/id ]; then\r\n    if [ -z \"$EUID\" ]; then\r\n        # ksh workaround\r\n        EUID=`id -u`\r\n        UID=`id -ru`\r\n    fi\r\n    USER=\"`id -un`\"\r\n    LOGNAME=$USER\r\n    MAIL=\"/var/spool/mail/$USER\"\r\nfi\r\n\r\n# Path manipulation\r\nif [ \"$EUID\" = \"0\" ]; then\r\n    pathmunge /sbin\r\n    pathmunge /usr/sbin\r\n    pathmunge /usr/local/sbin\r\nelse\r\n    pathmunge /usr/local/sbin after\r\n    pathmunge /usr/sbin after\r\n    pathmunge /sbin after\r\nfi\r\n\r\nHOSTNAME=`/bin/hostname 2>/dev/null`\r\nHISTSIZE=1000\r\nif [ \"$HISTCONTROL\" = \"ignorespace\" ] ; then\r\n    export HISTCONTROL=ignoreboth\r\nelse\r\n    export HISTCONTROL=ignoredups\r\nfi\r\n\r\nexport PATH USER LOGNAME MAIL HOSTNAME HISTSIZE HISTCONTROL\r\n\r\n# By default, we want umask to get set. This sets it for login shell\r\n# Current threshold for system reserved uid/gids is 200\r\n# You could check uidgid reservation validity in\r\n# /usr/share/doc/setup-*/uidgid file\r\nif [ $UID -gt 199 ] && [ \"`id -gn`\" = \"`id -un`\" ]; then\r\n    umask 002\r\nelse\r\n    umask 022\r\nfi\r\n\r\nfor i in /etc/profile.d/*.sh ; do\r\n    if [ -r \"$i\" ]; then\r\n        if [ \"${-#*i}\" != \"$-\" ]; then\r\n            . \"$i\"\r\n        else\r\n            . \"$i\" >/dev/null 2>&1\r\n        fi\r\n    fi\r\ndone\r\n\r\nunset i\r\nunset pathmunge\r\n\r\nPATH=/usr/local/webserver/php/bin:$PATH\r\nexport PATH\r\n```\r\n要是刚才的修改马上生效,需要执行以下代码\r\n```sh\r\n[root@AY140529210959Z ~]# source /etc/profile\r\n```\r\n这时再查看系统环境变量,就能看见刚才加的东西已经生效了\r\n```sh\r\n[root@AY140529210959Z ~]# echo $PATH\r\n/usr/local/webserver/php/bin:/usr/lib/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin\r\n```\r\n现在就能直接使用php命令了(而不是像之前写很长一串```/usr/local/webserver/php/bin/php -v```),例如查看当前php的版本\r\n```sh\r\n[root@AY140529210959Z ~]# php -v\r\nPHP 5.3.8 (cli) (built: Jun 27 2012 14:28:20)\r\nCopyright (c) 1997-2011 The PHP Group\r\nZend Engine v2.3.0, Copyright (c) 1998-2011 Zend Technologies\r\n```\r\n\r\n方法二:在用户目录下的.bash_profile文件中增加变量【对单一用户生效(永久的)】\r\n--------------------------------------------------------------------------------\r\n用VI在用户目录下的.bash_profile文件中增加变量,改变量仅会对当前用户有效,并且是“永久的”。具体操作和方法1一样,这里就不在列举代码了。\r\n\r\n方法三:直接运行export命令定义变量【只对当前shell(BASH)有效(临时的)】\r\n----------------------------------------------------------------------------\r\n在shell的命令行下直接使用[export变量名=变量值]定义变量,该变量只在当前的shell(BASH)或其子shell(BASH)下是有效的,shell关闭了,变量也就失效了,再打开新shell时就没有这个变量,需要使用的话还需要重新定义。例如\r\n```sh\r\nexport PATH=/usr/local/webserver/php/bin:$PATH\r\n```
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6923, '20150212093434', '20150212093434', '2015-02-12 01:34:36', '2019-03-25 21:29:22', '坐上回家的车了。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6924, '20150212130401', '20150212130401', '2015-02-12 05:04:02', '2019-03-25 21:29:22', '出发了。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6925, '20150213170700', '20150213170700', '2015-02-13 09:07:01', '2019-03-25 21:29:22', '到家了。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (6998, 'markdown-generated-according-to-the-title-of-the-article-article-directory', 'Markdown根据文章标题生成文章目录', '2015-02-16 13:21:57', '2019-03-25 22:51:40', '前言\r\n====\r\n最近把博客的文章换成了markdown,发现突然文章索引插件不能用了。分析了下,发现原因是,我的文章存储的的是markdown,在页面上是用marked.js转换成html的,这个需要在页面加载完成后执行。而插件需要提取html的h1~h6标签,但插件确是在页面展现之前调用,因此需要另辟蹊径。\r\n\r\n我的方案\r\n========\r\n作为程序员,这点事还难得倒吗?想了想,so easy。只需要在marked.js执行后在用js生成即可。具体的步骤如下:\r\n\r\n步骤1 页面修改\r\n----------\r\n找到主题的single.php目录(我的在```/wp-content/themes/shizzo/single.php```),页面文章开始的地方上需要添加以下代码:\r\n```html\r\n\r\n
    \r\n

    目录[-]

    \r\n
    \r\n
    \r\n```\r\n\r\n步骤2 添加js和css\r\n-------------\r\n在主题的style.css添加下面的css代码:\r\n```css\r\n/*导航 15-02-15 By 唐有炜*/\r\n.BlogAnchor {\r\n background: #f4f7f9;\r\n padding: 10px;\r\n line-height: 180%;\r\n}\r\n.BlogAnchor p {\r\n font-size: 18px;\r\n color: #15a230;\r\n margin-bottom: 0.3em;\r\n}\r\n.BlogAnchor .AnchorContent {\r\n padding: 5px 0px;\r\n}\r\n.BlogAnchor li {\r\n /*text-indent: 20px;*/\r\n font-size: 14px;\r\n list-style:none;\r\n}\r\n#AnchorContentToggle {\r\n font-size: 13px;\r\n font-weight: normal;\r\n color: #FFF;\r\n display: inline-block;\r\n line-height: 20px;\r\n background: #5cc26f;\r\n font-style: normal;\r\n padding: 1px 8px;\r\n margin-right: 10px;\r\n}\r\n.BlogAnchor a:hover {\r\n color: #5cc26f;\r\n}\r\n.BlogAnchor a {\r\n text-decoration: none;\r\n}\r\n```\r\n在页面添加js,只要能调用即可,我的放在我自己写的插件里面的init.js里面,代码如下:\r\n```js\r\n//*博客首页JS处理\r\n//*作者:唐有炜\r\n//*时间:2015年02月06日\r\nvar $ =jQuery.noConflict();\r\n\r\n$(function(){\r\n make_menu();\r\n});\r\n\r\n//添加文章目录\r\nfunction make_menu(){\r\n//在文章中查找title并填充到div AnchorContent中\r\n$(\".markdown-body\").find(\"h1,h2,h3,h4,h5,h6\").each(function(i, item) {\r\n var tag = $(item).get(0).localName;\r\n //console.log(tag);\r\n $(item).attr(\"id\", \"wow\" + i);\r\n //$(\"#AnchorContent\").append(\'
  1. \' +(i+1)+\' \'+ $(this).text() + \'
  2. \');\r\n $(\"#AnchorContent\").append(\'
  3. \'+ $(this).text() + \'
  4. \');\r\n $(\".newh1\").css(\"margin-left\", 0);\r\n $(\".newh2\").css(\"margin-left\", 20);\r\n $(\".newh3\").css(\"margin-left\", 40);\r\n $(\".newh4\").css(\"margin-left\", 60);\r\n $(\".newh5\").css(\"margin-left\", 80);\r\n $(\".newh6\").css(\"margin-left\", 100);\r\n});\r\n//展开收起\r\n $(\"#AnchorContentToggle\").click(function(){\r\n //alert(\"aaa\");\r\n $(\"#AnchorContent\").toggle();\r\n });\r\n//点击动画效果\r\n$(\".anchor-link\").click(function() {\r\n $(\"html,body\").animate({\r\n scrollTop: $(\"#wow1\").offset().top\r\n },\r\n 1000);\r\n});\r\n```\r\n效果如下\r\n========\r\n![](http://bcs.duapp.com/terwer/blog/2015/02/QQ%E6%88%AA%E5%9B%BE20150216215454.png)\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (7061, 'study-on-the-wordpress-xml-rpc-api', '初探WordPress XML-RPC api', '2015-02-17 05:56:16', '2019-03-25 21:29:22', '
    什么是XML-RPC\r\n=============\r\n未完待续\r\n
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (7069, 'windows2003-iis6-deployment-mvc3-and-mvc4-programs', 'windows server 2003 IIS6 部署MVC4程序', '2015-02-17 08:53:56', '2019-03-25 21:29:22', '
    步骤如下\r\n========\r\n1.服务器上安装SP2 和 IIS6\r\n\r\n2.安装.Net Framework3.5 SP1(完整安装包,包含2.0 2.0SP1,237MB那个安装包)\r\n\r\n3.安装.Net Framework4.0\r\n\r\n4.安装WindowsServer2003-KB968930-x86-CHS.exe,PowerShell 2.0的补丁(下载地址:http://www.microsoft.com/zh-cn/download/details.aspx?id=4045)\r\n\r\n5.安装wic_x86_chs.exe,windows图像处理组件(下载地址:http://www.microsoft.com/zh-cn/download/details.aspx?id=32)\r\n\r\n6.安装AspNetMVC3Setup.exe(http://www.microsoft.com/zh-cn/download/details.aspx?id=4211)\r\n\r\n7.安装AspNetMVC4Setup.exe(http://www.microsoft.com/zh-cn/download/details.aspx?id=30683)\r\n\r\n8.重新注册IIS,C:WINDOWSMicrosoft.NETFrameworkv4.0.30319aspnet_regiis.exe -i\r\n\r\n请尽量按照如上顺序安装。
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (7072, 'android-emulator-avd-shortcuts', 'Android模拟器(AVD)快捷键', '2015-02-18 07:29:40', '2019-03-25 21:29:22', '
    对应关系如下:\r\n\r\nHome键(小房子键)\r\n==================\r\n在键盘上映射的就是```home```键,这倒是很好记。\r\n\r\nMenu键\r\n======\r\n用于打开菜单的按键,在键盘上映射的是```F2```键,PgUp键同样可以。另外,看英文原文的意思,貌似这个键在某些机型上会被设计为左软件(left softkey)\r\n\r\nStart键\r\n=======\r\n这个键在模拟器和G1真机上我都没有找到到底是哪个键。映射的是```Shift+F2```或```PgDn```,某些机型会被设计为```右软键```(right softkey)。\r\n\r\nBack键\r\n=======\r\n返回键,用户返回上一个UI或者退出当前程序。键盘上映射```ESC```键。\r\n\r\nCall/Dial键(电话键)\r\n======================\r\n接听来电或启动拨号面板,这是一部手机最基本的功能键。PC键盘映射为```F3```键。   
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (7076, '20150220204807', '20150220204807', '2015-02-20 12:48:08', '2019-03-25 21:29:22', '2015,为生活而活,为梦想奋斗。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (7077, '20150220205439', '20150220205439', '2015-02-20 12:54:40', '2019-03-25 21:29:22', '2015,真正专注安卓移动互联网开发。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (7098, 'the-20150224184735', '20150224184735', '2015-02-24 10:47:36', '2019-03-25 21:29:22', '2015,多点干货。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (7105, 'no-resource-found-that-matches-the-given-name-style-themeappcompatlight', '关于 No resource found that matches the given name '@style/Theme.AppCompat.Light'', '2015-02-24 11:34:42', '2019-03-25 21:29:22', '
    解决方案\r\n========\r\n方法一:直接下载support library。\r\n[http://developer.android.com/tools/support-library/setup.html](http://developer.android.com/tools/support-library/setup.html)\r\n\r\n方法二:在Eclipse中更新SDK(来自stackoverflow)\r\n==============================================\r\n\r\nGo to the tabs at the top and select ( Windows -> Android SDK Manager ). Under the \'extras\' section, check \'Android Support Library\' and check it for installation.\r\n\r\nenter image description here\r\n\r\nAfter that, the AppCompat library can be found at:\r\n\r\nandroid-sdk/extras/android/support/v7/appcompat\r\nYou need to reference this AppCompat library in your Android project.\r\n\r\nImport the library into Eclipse.\r\n\r\nRight click on your Android project.\r\nSelect properties.\r\nClick \'add...\' at the bottom to add a library.\r\nSelect the support library\r\nClean and rebuild your project.\r\n
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (7109, 'android-appcompat-v7-engineering-error-when-you-create-a-new-project-and-a-red-exclamation', '关于更新Android SDK后,新建项目时出现appcompat_v7工程', '2015-02-24 12:00:49', '2019-03-25 21:29:22', '
    前言\r\n====\r\n最近手贱更新了Android SDK,版本是22.6.0的话,每次创建一个项目就会出现一个appcompat_v7工程;然后我升级到最新的版本23.0.4之后,创建第一个项目,也会出现一个appcompat_v7工程,但创建多个项目的话,appcompat_v7工程也仅有一个,但有错误;\r\n\r\n原因\r\n====\r\nappcompat_v7是Google的一个兼容包,就是一个支持库,项目新建后之所以会生成appcomat_v7工程,是为了能兼容2.2以上的版本,eclipse在新建项目的时候自动关联了所需要的lib;\r\n\r\n关联的方式是:项目->Properies->Android->Libary;\r\n\r\n你会看到appcomat_v7被作为lib加载了进来,如果不想引用这个lib,把它删除了,关联就解除了,也就不能兼容以前的版本了;\r\n\r\n解决方案\r\n=========\r\n如果不想让appcompat_v7自动生成,可以在创建项目时,将Minimum Required SDK(即兼容的最小版本)设置为4.0,那就不会有这个工程的出现了;\r\n\r\n另外,如果不想生成appcompat_v7工程的话,就要引入appcompat_v7的jar包作为支持。\r\n
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (7118, 'mysql-batch-delete-non-make-prefix-table', 'MySQL批量删除非制定前缀的表', '2015-02-24 16:02:59', '2019-03-25 23:56:53', '解决方案\r\n=====\r\n可以查出SQL,然后再删除,代码如下:\r\n```sql\r\nSELECT CONCAT( \'DROP TABLE \', GROUP_CONCAT(table_name) , \';\' ) AS statement\r\nFROM information_schema.tables\r\nWHERE table_schema = \'zhaopin\' AND table_name NOT LIKE \'T_%\';\r\n```\r\n查出的结果为:\r\n```sql\r\nDROP TABLE all_objects,all_parameters,all_sql_modules,all_views,allocation_units,assemblies,assembly_files,assembly_modules,assembly_references,assembly_types,asymmetric_keys,backup_devices,certificates,change_tracking_databases,change_tracking_tables,check_constraints,column_domain_usage,column_privileges,column_type_usages,column_xml_schema_collection_usages,columns,computed_columns,configurations,constraint_column_usage,constraint_table_usage,conversation_endpoints,conversation_groups,conversation_priorities,credentials,crypt_properties,cryptographic_providers,data_spaces,database_audit_specification_details,database_audit_specifications,database_files,database_mirroring,database_mirroring_endpoints,database_mirroring_witnesses,database_permissions,database_principal_aliases,database_principals,database_recovery_status,database_role_members,databases,default_constraints,destination_data_spaces,dm_audit_actions,dm_audit_class_type_map,dm_broker_activated_tasks,dm_broker_connections,dm_broker_forwarded_messages,dm_brok;\r\n```\r\n然后执行该SQL即可。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (7186, '20150228195711', '20150228195711', '2015-02-28 11:57:12', '2019-03-25 21:29:22', '公有云赔本赚吆喝,私有云闷声发大财。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (7196, 'oneblog-development-series-of-the-welcome-page', 'Android版聚合博客客户端OneBlog开发系列之欢迎页面', '2015-03-01 06:54:11', '2019-03-25 21:29:22', '
    项目简介\r\n========\r\n这个是我自己写的开源的聚合博客发布系统Android版[OneBlogAndroid](https://github.com/terwer/OneBlogAndroid),Winform版和WPF版[请看这里](https://github.com/terwer/OneBlog),计划支持wordpress、新浪、QQ空间、网易博客、博客园、CSDN等。\r\n\r\n前言\r\n====\r\n本文将开始正式开发,从欢迎界面做起,最终的样子大概是这样:\r\n![](http://www.terwer.com/wp-content/uploads/2015/02/Screenshot_2015-03-01-15-05-47-576x1024.png)\r\n\r\n开发流程\r\n========\r\n\r\n未完待续(笔者工作很忙,不能及时更新,请耐心等待。。。,有问题请[留言](http://www.terwer.com/guestbook.html#respond))\r\n\r\n\r\n系列导航\r\n========\r\n1.需求分析\r\n\r\n2.业务分析与原型设计\r\n\r\n3.界面设计\r\n\r\n4.服务端api设计\r\n* 4.1 [初探Wordpress XML-RPC api](http://www.terwer.com/study-on-the-wordpress-xml-rpc-api.html)\r\n\r\n5、交互设计\r\n* 5.1 [Android版聚合博客客户端OneBlog开发系列之欢迎页面](http://www.terwer.com/oneblog-development-series-of-the-welcome-page.html)\r\n\r\n6、测试\r\n\r\n7、发布到商店\r\n

    转载请注明:特维博客 » Android版聚合博客客户端OneBlog开发系列之欢迎页面

    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (7207, 'e-commerce-platform-to-combat-the-stock-dock-with-the-erp-solution', '电商平台实战之库存与ERP对接解决方案', '2015-03-06 07:16:26', '2019-03-25 23:54:35', '需求分析\r\n========\r\n当前系统中库存是针对商品和货品的,没有细化到门店,而根据最近几个项目中客户的需求,有的客户需求库存详细到门店,并且涉及到与ERP系统中的库存对接。因此需要改进系统来适应这些需求,同时还要保证和不需要细化到门店的系统保持兼容。\r\n\r\n目前的解决方案是将库存信息独立出来与商品、货品和门店相关,并且商品在不需要门店的情况下,属于总店。\r\n\r\n另外,库存中增加了锁库存,只有在发货的时候采取扣减真实库存。\r\n\r\n表的结构修改\r\n============\r\n* 表:ZtdGoodsStock\r\n\r\n字段名|类型|长度|是否允许为空|备注\r\n---|---|---|---|---\r\nID|Int||否|自增ID\r\nProductID|Int||否|商品ID\r\nGoodsID|Int||否|货品ID\r\nGoodsNo|Varchar|20|否|货品编号\r\nZtdNo|Varchar|50|否|门店编号\r\nStock|Int||否|库存\r\nLockStock|Int||否|锁库存\r\n\r\n记录处理流程\r\n============\r\n\r\n### 1、商品信息处理\r\n* 1.1 商品添加修改时的处理\r\n#### 添加商品时,先添加商品信息和货品信息,然后在门店库存表插入记录(默认添加在总店),然后统计货品和商品在所有门店的库存并更新货品和商品的库存。\r\n存储过程控制如下:\r\n\r\n##### 构造货品ID集合临时表,添加货品库存信息到门店库存表(总店)\r\n\r\n```sql\r\n...\r\n--注:#g为待插入货品信息临时表\r\ninsert into goods(productid,goodsno,marketprice,memberprice,weight,volume,score,storage,goodsname,supplierid,props,propsdesc,propsname,costprice) select * from #g\r\n--货品ID集合临时表\r\nselect props,g.goodsid into #goodsids from goods g(nolock)\r\nwhere g.productid=@productid --and g.goodsid not in(select goodsid from #g) by liwenhai 20130717\r\n\r\n--添加货品库存信息到门店库存表(总店)\r\nselect g.ProductID,g.GoodsID,g.GoodsNo,\'0\' as ZtdNo,g.Storage as stock,0 as LockStock into #zgs from #goodsids gt,goods g(nolock)\r\nwhere gt.goodsid=g.goodsid\r\ninsert into ZtdGoodsStock(ProductID,GoodsID,GoodsNo,ZtdNo,Stock,LockStock)\r\nselect * from #zgs\r\n...\r\n```\r\n\r\n##### 统计所有门店的库存并更新货品和商品表库存\r\n\r\n```sql\r\n...\r\n------------------------------------------------------------------------\r\n--有多规格的情况--------------------------------------------------------\r\n-------------------------------------------------------------------------\r\n--统计所有门店的库存并更新货品和商品表库存\r\n--更新货品库存和商品库存\r\n --货品库存\r\nupdate goods set storage=isnull((select sum(zgs.stock) from ztdgoodsstock zgs where g.goodsid=zgs.goodsid),0)\r\nfrom #goodsids g\r\n --商品库存\r\nupdate product set storage=isnull((select sum(g.storage) from goods g(nolock) where g.productid=@productid),0)\r\n...\r\n```\r\n\r\n```\r\n-------------------------------------------------------------\r\n--没有多规格的情况--------------------------------------------\r\n--------------------------------------------------------------\r\n...\r\n--获取当前货品id\r\nselect @gid=@@identity\r\n--添加货品库存信息到门店库存表(总店)\r\ninsert into ZtdGoodsStock(ProductID,GoodsID,GoodsNo,ZtdNo,Stock) values (@productid,@gid,@productno,\'0\',@storage)\r\n\r\n--统计所有门店的库存并更新货品和商品表库存\r\n--更新货品库存和商品库存\r\n --货品库存\r\nupdate goods set storage=(select sum(zgs.Stock) from ZtdGoodsStock as zgs where GoodsID=@gid group by zgs.GoodsId) where GoodsID=@gid\r\n --商品库存\r\nupdate Product set Storage =(select sum(storage) FROM Goods as g where g.ProductID=@productid) where ProductID=@productid\r\n...\r\n```\r\n### 修改商品时,先修改商品和货品信息(可能需要更新门店库存表),这里然后统计货品和商品在所有门店的库存并更新到货品表和商品表。\r\n#### 有多规格的情况\r\n删除不存在的货品\r\n```sql\r\n--删除不存在的货品\r\ndelete from goods where goods.productid=@productid and goods.goodsid not in (select goodsid from #g where #g.goodsid\'\')\r\n--删除该货品对应的门店的库存信息\r\ndelete from ztdgoodsstock where productid=@productid and ztdgoodsstock.goodsid not in(select goodsid from #g where #g.goodsid\'\')\r\n```\r\n\r\n更新货品\r\n```sql\r\n--更新货品\r\nupdate g\r\nset g.goodsno=gt.goodsno,g.marketprice=gt.marketprice,g.memberprice=gt.memberprice,g.weight=gt.weight,g.score=gt.score,/*g.storage=gt.storage,*/g.goodsname=gt.goodsname,g.props=gt.props,g.propsdesc=gt.propsdesc,g.propsname=gt.propsname,costprice=gt.costprice\r\nfrom goods g(nolock),#g gt\r\nwhere g.goodsid=gt.goodsid\r\n--更新该货品对应门店的总店库存信息\r\nupdate zgs\r\nset zgs.goodsno=gt.goodsno,zgs.stock=gt.storage\r\nfrom ztdgoodsstock zgs,#g gt\r\nwhere zgs.goodsid=gt.goodsid and zgs.ztdno=\'0\'\r\n```\r\n\r\n插入新货品\r\n```sql\r\n--插入新货品\r\n insert into goods(productid,goodsno,marketprice,memberprice,weight,volume,score,storage,goodsname,supplierid,props,propsdesc,propsname,costprice)\r\n select productid,goodsno,marketprice,memberprice,weight,volume,score,storage,goodsname,supplierid,props,propsdesc,propsname,costprice\r\n from #g where #g.goodsid=\'\'\r\n--添加该货品对应门店的新库存信息\r\n select g.ProductID,g.GoodsID,g.GoodsNo,\'0\' as ZtdNo,g.Storage as stock,0 as LockStock into #zgs from #g gt\r\n left join Goods g(nolock) on gt.goodsno=g.goodsno\r\nwhere gt.goodsid not in(select GoodsID from goods g where g.productid=@productid)\r\n --避免重复插入\r\n insert into ZtdGoodsStock(ProductID,GoodsID,GoodsNo,ZtdNo,Stock,LockStock)\r\n select * from #zgs\r\n\r\n```\r\n\r\n统计所有门店的库存并更新货品和商品表库存\r\n```sql\r\n--统计所有门店的库存并更新货品和商品表库存\r\n --更新货品库存和商品库存\r\n --货品库存\r\n update goods set storage= tb.stock\r\n from\r\n (\r\n select goodsid,sum(zgs.stock) as stock\r\n from ztdgoodsstock zgs(nolock)\r\n where zgs.productid=@productid\r\n group by zgs.goodsid\r\n ) as tb\r\n where goods.goodsid=tb.goodsid\r\n --update goods set storage=isnull((select sum(zgs.stock) from ztdgoodsstock zgs(nolock),#g g(nolock) where zgs.goodsid=g.goodsid group by zgs.goodsid),0)\r\n --商品库存\r\n update product set storage=isnull((select sum(g.storage) from goods g(nolock) where g.productid=@productid),0)\r\n```\r\n#### 没有多规格的情况\r\n删除多规格取消时的数据\r\n```sql\r\nupdate top (1) goods\r\n set goodsno=@productno,marketprice=@marketprice,memberprice=@memberprice,weight=@weight,volume=@Volume,score=@score,/*storage=@storage,*/goodsname=@productname,props=null,propsdesc=null,costprice=@costprice\r\n where productid=@productid\r\n\r\n --删除多规格取消时的数据\r\n delete from goods where isnull(props,\'\')\'\' and isnull(propsdesc,\'\')\'\' and productid=@productid\r\n --获取最新的goodsid,设置groupprice要用到\r\n declare @gid int\r\n select @gid=goodsid from goods g(nolock)where productid=@productid\r\n --多规格取消时门店的库存\r\n delete from ztdgoodsstock where goodsid@gid and productid=@productid\r\n```\r\n更新门店(总店)库存\r\n```sql\r\n --更新门店(总店)库存\r\n update top(1) ztdgoodsstock\r\n set stock=@storage\r\n where productid=@productid\r\n```\r\n\r\n统计所有门店的库存并更新货品和商品表库存\r\n```sql\r\n--统计所有门店的库存并更新货品和商品表库存\r\n --更新货品库存和商品库存\r\n --货品库存\r\n update goods set storage=(select sum(zgs.Stock) from ZtdGoodsStock as zgs where zgs.productid=@productid group by zgs.GoodsId) where productid=@productid\r\n --商品库存\r\n update Product set Storage =(select sum(storage) FROM Goods as g where g.ProductID=@productid) where ProductID=@productid\r\n```\r\n### 删除商品时,同步删除门店对应的库存。\r\n```sql\r\n --删除货品在门店的库存信息\r\n delete ztdgoodsstock from ztdgoodsstock,#temp where ztdgoodsstock.productid=#temp.[value]\r\n --删除货品信息\r\n delete goods from goods,#temp where goods.productid=#temp.[value]\r\n --删除商品信息\r\n delete product from product,#temp where product.productid=#temp.[value]\r\n```\r\n* 1.2 门店后台更新库存\r\n* 1.3 erp同步库存\r\n\r\n### 2、订单流程的处理\r\n* 2.1 详情页面加入购物车判断\r\n* 2.2 购物车页面更新购物车\r\n* 2.3 生成订单时的判断\r\n* 2.4 后台取消订单\r\n* 2.5 发货\r\n\r\n未完待续(笔者工作很忙,不能及时更新,请耐心等待。。。,有问题请[留言](http://www.terwer.com/guestbook.html#respond))\r\n=======================================================================================================================', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (7239, 'development-build-target-android-sdk-in-eclipse-and-meaning-of-ndroid-targetsdkversion-and-other-versions-in-androidmanifestxml', 'Eclipse中Android开发Build Target SDK in 和AndroidManifest.xml中的android:targetSdkVersion及其他版本的含义', '2015-03-02 06:06:56', '2019-03-25 21:29:22', '
    minSDKVersion\r\n=============\r\nminSDKVersion - 低于此SDK版本,Android程序将无法运行。\r\n\r\ntargatSDKVersion\r\n================\r\ntargatSDKVersion - 应用程序的运行环境。对于一个有最新SDK版本的SDK,如果他的版本为21,但是你把target sdk版本设置成了19,意味着应用程序(包括主题、UI、类库等)在这个设备里面将使用19版本。\r\n\r\nProject Build Target\r\n====================\r\nProject Build Target - 当你选择一个Project Build Target版本时,意味着你的apk和生成的class将依靠这个版本来编译。例如,如果你选择了16,但是你使用了@JavaScriptInterface注解,应用程序将无法使用。\r\n\r\nmaxSDKVersion\r\n=============\r\nmaxSDKVersion - 意味着高于此版本,用于程序将无法安装。
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (7245, 'android-application-development-and-activity-label-name', '关于安卓开发应用程序名和activity标签名字', '2015-03-02 06:31:36', '2019-03-25 21:29:22', '
    关于安卓开发应用程序名和activity标签名字\r\n=============\r\n情景重现\r\n========\r\n在模拟器中,程序列表中应用程序名字和activity界面标题一样,于是我把activity标签改了,然后运行,可是这个应用程序名字也跟着改了,而我们想让那个运行界面最上面标签但是应用程序名字不变。\r\n\r\n原因分析与解决方案\r\n===================\r\n桌面上显示的程序名字默认是程序启动activity的label,可以看一下下面的代码,在桌面上显示的不是application而是activity,只要你修改该activity的标签程序名字也会跟着变,一般的程序的application节点的label标签和启动activity的label内容都是一致的。\r\n\r\n```xml\r\n\r\n        \r\n            \r\n                \r\n\r\n                \r\n            \r\n        \r\n\r\n```\r\n
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (7262, '20150302231713', '20150302231713', '2015-03-02 15:17:14', '2019-03-25 21:29:22', '从现在开始,少做无意义的重复工作。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (7263, 'finishing-my-blog', '整理一下我的博客', '2015-03-03 07:05:20', '2019-03-25 23:31:39', '
    存储过程代码如下\r\n================\r\n```sql\r\n/*\r\n=============================================\r\nAuthor:terwer\r\nCreate date:2015-03-03\r\nDescription:整理我的博客\r\nUpdate History\r\n*/\r\n/*\r\nVersion:V0.1\r\nAuthor:terwer\r\nTime:2015.03.03\r\nDescription:\r\n整理我的博客。\r\n*/\r\n/*\r\n==============================================\r\n*/\r\nDROP PROCEDURE IF EXISTS `terwer_proc_post_finished`;\r\n\r\nCREATE DEFINER = CURRENT_USER PROCEDURE `terwer_proc_post_finished`(IN post_name VARCHAR(8000))\r\n    SQL SECURITY INVOKER\r\nBEGIN\r\n/*参数处理*/\r\nSET @post_name=post_name;\r\n\r\n/*当前文章ID*/\r\nselect @current_post_id:=(SELECT id FROM wp_posts AS p where p.post_name=@post_name LIMIT 1) AS \'当前文章ID\';\r\n/*查询所有文章数目*/\r\nSELECT COUNT(1) AS \'所有文章数目\' FROM wp_posts;\r\n/*查询修改好的文章数目*/\r\nSELECT COUNT(1) AS \'修改好的文章数目\' from wp_posts AS p\r\nwhere p.id in (select post_id from wp_postmeta where meta_key=\'terwer_post_finished\' AND meta_value=\'good\');\r\n/*查询修改好的文章*/\r\nSELECT p.ID,p.post_title  as \'修改好的文章列表\' ,p.post_name FROM wp_posts AS p\r\nWHERE p.id  IN (SELECT post_id FROM wp_postmeta WHERE meta_key=\'terwer_post_finished\' )\r\nLIMIT 0,10;\r\n/*查询未修改好的文章数目*/\r\nSELECT COUNT(1) AS \'未修改好的文章数目\' from wp_posts AS p\r\nwhere p.id not in (select post_id from wp_postmeta where meta_key=\'terwer_post_finished\' AND meta_value=\'good\');\r\n/*查询未修改好的文章*/\r\nSELECT p.ID,p.post_title  as \'未修改好的文章列表\' ,p.post_title,p.post_name FROM wp_posts AS p\r\nWHERE p.post_title\'\' and p.id NOT IN (SELECT post_id FROM wp_postmeta WHERE meta_key=\'terwer_post_finished\' )\r\nLIMIT 0,10;\r\n/*修改当前文章*/\r\nINSERT INTO wp_postmeta(post_id,meta_key,meta_value)\r\nSELECT @current_post_id,\'terwer_post_finished\',\'good\'\r\nFROM DUAL\r\nWHERE NOT EXISTS(SELECT * FROM wp_postmeta WHERE post_id=@current_post_id AND meta_key=\'terwer_post_finished\');\r\nSELECT * FROM wp_postmeta ORDER BY meta_id DESC LIMIT 0,5;\r\nEND\r\n```\r\n\r\n存储过程调用\r\n============\r\n\r\n```sql\r\nCALL terwer_proc_post_finished(\"finishing-my-blog\");\r\n```\r\n\r\n运行效果\r\n========\r\n\r\n```shell\r\nmysql> CALL terwer_proc_post_finished(\"finishing-my-blog\");\r\n ------------\r\n| 当前文章ID |\r\n ------------\r\n|       7263 |\r\n ------------\r\n1 row in set\r\n\r\n --------------\r\n| 所有文章数目 |\r\n --------------\r\n|         1119 |\r\n --------------\r\n1 row in set\r\n\r\n ------------------\r\n| 修改好的文章数目 |\r\n ------------------\r\n|                1 |\r\n ------------------\r\n1 row in set\r\n\r\n ------ ------------------ -------------------\r\n| ID   | 修改好的文章列表 | post_name         |\r\n ------ ------------------ -------------------\r\n| 7263 | 整理一下我的博客 | finishing-my-blog |\r\n ------ ------------------ -------------------\r\n1 row in set\r\n\r\n --------------------\r\n| 未修改好的文章数目 |\r\n --------------------\r\n|               1118 |\r\n --------------------\r\n1 row in set\r\n\r\n ------ ------------------------------------------- ------------------------------------------- -----------------------------------------------\r\n| ID   | 未修改好的文章列表                        | post_title                                | post_name                                     |\r\n ------ ------------------------------------------- ------------------------------------------- -----------------------------------------------\r\n| 1992 | RSS订阅                                   | RSS订阅                                   | rssblog                                       |\r\n|   67 | 首页                                      | 首页                                      | home                                          |\r\n|  749 | JavaScript                                | JavaScript                                | js                                            |\r\n| 5198 | js在IE8 兼容String没有trim方法            | js在IE8 兼容String没有trim方法            | original-js-ie8-compatible-string-trim-method |\r\n| 4451 | 20131211162635                            | 20131211162635                            | 20131211162635                                |\r\n| 1985 | 版权声明                                  | 版权声明                                  | copyright                                     |\r\n| 2006 | 网站日记                                  | 网站日记                                  | events                                        |\r\n| 3161 | 史上最强最全VC6.0到VS2013全部版本下载地址 | 史上最强最全VC6.0到VS2013全部版本下载地址 | vs-downloads-from-vc6-to-vs2013               |\r\n| 3177 | Android中Spinner数据绑定的简单实现        | Android中Spinner数据绑定的简单实现        | spinner-simple-data-bind                      |\r\n| 3185 | 2013年10月28日 13:17:11                   | 2013年10月28日 13:17:11                   | 2013年10月28日-131711    |\r\n ------ ------------------------------------------- ------------------------------------------- -----------------------------------------------\r\n10 rows in set\r\n\r\n --------- --------- ------------ --------------\r\n| meta_id | post_id | meta_key   | meta_value   |\r\n --------- --------- ------------ --------------\r\n|   21503 |    7295 | views      | 14           |\r\n|   21502 |    7295 | _edit_lock | 1425435698:1 |\r\n|   21499 |    7295 | _edit_last | 1            |\r\n|   21482 |    7287 | _edit_last | 1            |\r\n|   21481 |    7287 | _edit_lock | 1425394334:1 |\r\n --------- --------- ------------ --------------\r\n5 rows in set\r\n\r\nQuery OK, 0 rows affected\r\n\r\nmysql>\r\n```\r\n\r\n本文来自 [特维博客](http://www.terwer.com) ,作者:[terwer](http://www.terwer.com/guestbook.html#respond) ,使用Markdown原创发布,未经允许,谢绝转载。  
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (7287, 'use-entityframework-linq-to-compare-date-and-time', 'Entityframework中使用LINQ比较日期和时间', '2014-03-03 14:53:51', '2019-03-25 21:29:22', '
    Entityframework中使用LINQ比较日期和时间\r\n=======================================\r\n这里简介调用了SQL Server的DataDiff函数,关于DataDiff函数,[请看这里](https://msdn.microsoft.com/en-us/library/ms189794(v=sql.105).aspx)。\r\n\r\n代码如下\r\n\r\n```cs\r\n/* 处理过滤规则 */\r\nif ( null != filterRules )\r\n{\r\n	JArray rules = (JArray) JsonConvert.DeserializeObject( filterRules );\r\n	foreach ( var f in rules )\r\n	{\r\n		string	field	= f[\"field\"].ToString();\r\n		string	op	= f[\"op\"].ToString();\r\n		string	value	= f[\"value\"].ToString();\r\n		switch ( field )\r\n		{\r\n		case \"employ_addTime\":\r\n			if ( !String.IsNullOrEmpty( value ) )\r\n			{\r\n				DateTime date = DateTime.Parse( value );\r\n				switch ( op )\r\n				{\r\n				case \"all\":\r\n					break;\r\n				case \"equal\":\r\n					emploies =\r\n						emploies.Where(\r\n							e => SqlFunctions.DateDiff( \"day\", e.employ_addTime, date ) == 0 );\r\n\r\n					break;\r\n				case \"notequal\":\r\n					emploies =\r\n						emploies.Where(\r\n							e => SqlFunctions.DateDiff( \"day\", e.employ_addTime, date ) != 0 );\r\n					break;\r\n				case \"less\":\r\n					emploies =\r\n						emploies.Where(\r\n							e => SqlFunctions.DateDiff( \"day\", e.employ_addTime, date ) > 0 );\r\n					break;\r\n				case \"greater\":\r\n					emploies.Where(\r\n						e => SqlFunctions.DateDiff( \"day\", e.employ_addTime, date ) < 0 );\r\n					break;\r\n				default:\r\n					break;\r\n				}\r\n			}\r\n			break;\r\n		}\r\n	}\r\n}\r\n```\r\n\r\n\r\n
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (7295, 'sql-server-uses-a-cursor-structure-skumap', 'SQL SERVER使用游标构造SkuMap', '2015-02-06 02:15:55', '2019-03-25 23:59:34', '需求背景\r\n========\r\n通常,为了减少前端传输的压力,可以把货品信息构造成json存储到数据库,然后在前台直接用js调用。\r\n\r\n代码如下\r\n========\r\n\r\n```sql\r\n--构造SkuMap并更新到商品表\r\ndeclare @skumap varchar(max),@propid varchar(50),@goodsid int,@goodsmprice decimal(18,2),@goodsprice decimal(18,2),@goodsstock int,@goodslockstock varchar(50),@goodsno varchar(50),@goodsweight decimal(18,3)\r\n--定义遍历当前商品的不同规格的货品的游标\r\ndeclare goods_items_cursor cursor for\r\nselect goodsid,goodsno,marketprice,memberprice,storage,lockstorage,weight,props\r\nfrom goods\r\nwhere productid=@ProductID\r\norder by goodsid asc\r\nselect @skumap=\'{\'\r\n--遍历游标\r\nopen goods_items_cursor\r\nfetch next from goods_items_cursor into\r\n@goodsid,@goodsno,@goodsmprice,@goodsprice,@goodsstock,@goodslockstock,@goodsweight,@propid\r\nwhile @@fetch_status = 0\r\nbegin\r\nselect @skumap=@skumap \'\"\' isnull(@propid,\'0:0;0:0\') \'\":{\"skuId\":\"\' cast(@goodsid as varchar(50)) \'\",\"mprice\":\"\' cast(@goodsmprice as varchar(50)) \'\",\"price\":\"\' cast(@goodsprice as varchar(50)) \'\",\"stock\":\"\' cast(@goodsstock as varchar(50)) \'\",\"lockstock\":\"\' cast(@goodslockstock as varchar(50)) \'\",\"weight\":\"\' cast(@goodsweight as varchar(50)) \'\",\"code\":\"\' @goodsno \'\"},\'\r\nfetch next from goods_items_cursor into\r\n@goodsid,@goodsno,@goodsmprice,@goodsprice,@goodsstock,@goodslockstock,@goodsweight,@propid\r\nend\r\n--遍历结束\r\nclose goods_items_cursor\r\ndeallocate goods_items_cursor\r\n\r\n--去掉最后一个逗号\r\nif len(@skumap)>1\r\nselect @skumap=substring(@skumap,1,len(@skumap)-1)\r\nselect @skumap=@skumap \'}\'\r\n```', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (7328, 'virtualbox-by-putty-connection-centos', 'WIN7通过PuTTY连接VirtualBox虚拟机里面的CentOS', '2015-03-09 14:10:14', '2019-09-06 16:46:21', '>
    2019/3/27 15:16 验证通过
    \r\n\r\n\r\n查看IP\r\n====\r\n\r\n首先启动VirtualBox虚拟机,启动CentOS。CentOS默认使用 `nat` 网络,输入命令 ```ifconfig``` 查看ip。\r\n\r\n可以看到默认ip为 ``10.0.2.15``\r\n\r\n此处虚拟机中的ip显然和我们的pc不在同一网段, 无法连接。\r\n\r\n端口转发配置PC与VirtualBox的映射\r\n======================\r\n\r\nVirtualBox提供了端口转发功能, 十分方便, 我们找到网络设置点击端口转发\r\n添加一条转发规则, 将Linux的SSH默认端口 `22` 转发到我们PC的 `2222`(此端口可以自己指定)\r\n\r\n![](https://terwer.oss-cn-qingdao.aliyuncs.com/bugucms/20190327151233.png)\r\n\r\n然后就可以在PuTTY里面用 ``127.0.0.1`` 端口22来连接CentOS了\r\n\r\n\r\n在Win7上使用PuTTY连接CentOS\r\n=====================\r\n\r\n\r\n输入账户登录\r\n\r\n```shell\r\nssh -p 2222 root@127.0.0.1\r\nlogin as: root\r\nroot@127.0.0.1\'s password:\r\nLast login: Mon Mar 9 09:52:15 2015\r\n[root@localhost ~]#\r\n```', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7337, 'the-20150310161808', '20150310161808', '2015-03-10 08:18:09', '2019-03-25 21:29:22', 'left join一定要记得加isnull', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (7349, 'schema-before-rookie-growth-path', '架构菜鸟成长之路之前言', '2015-03-18 14:52:29', '2019-03-25 21:29:22', '
    \r\n前言\r\n====\r\n<img style="float:left;margin-right:20px;width:200px;height:123px" src="http://bcs.duapp.com/terwer/blog/2015/03/2015-03-18_2324291.png" alt="" />\r\n\r\n很久之前就想写写这个系列的文章,奈何迟迟未能动笔。原因很多,一来,之前因为毕业时间不长,恐资历尚浅,不敢在大牛面前班门弄斧,二来,平时项目也很忙,基本不能静下心来总结这些。\r\n\r\n年后归来,本命年将至,才突然感概,不知不觉,我早已褪去大学的印记,成为职场熟手。然而,回想之前的目标,虽然仍然感觉里架构师很遥远,不过也算是了解甚至使用过不少架构了,暂且分享一下我对架构的思考,有些方面也算是现学现卖,[希望大家能一起交流](http://www.terwer.com/guestbook.html)。\r\n\r\n关于我\r\n======\r\n<img style="float:left;margin-right:20px" src="http://bcs.duapp.com/terwer/blog/2014/11/me.jpg" alt="" />\r\n装逼架构师(努力中)、业余文学爱好者。专注于项目架构、性能优化、算法研究,精通后端编程,熟练Java、.NET,目前研究Node.js。\r\n\r\n业余时间喜欢探索移动互联网开发,熟练Android。\r\n\r\n如果你也是一个热爱技术乐于分享的同道中人,可以[给我留言](http://www.terwer.com/guestbook.html) ,大家一起进步,我会抽时间尽量回复。\r\n\r\n系列导航\r\n========\r\n000 [架构菜鸟成长之路之前言](http://www.terwer.com/schema-before-rookie-growth-path.html)\r\n001 [架构菜鸟成长之路之从无架构谈起  - 回归本质](http://www.terwer.com/schema-starting-rookie-grow-from-no-schema.html)\r\n002 架构菜鸟成长之路之经典三层 - 简单封装\r\n003 架构菜鸟成长之路之四层 - 轻量级\r\n004 架构菜鸟成长之路之n层 - 重量级(IOC、AOP)\r\n005 架构菜鸟成长之路之DDD - 领域驱动设计\r\n006 架构菜鸟成长之路之SOA - 面向服务的体系结构\r\n007 架构菜鸟成长之路之OSGI - 模块化架构\r\n008 架构菜鸟成长之路之分布式 - 分布式架构\r\n009 架构菜鸟成长之路之restFul - restFul 架构\r\n。。。\r\nn 架构菜鸟成长之路之我的架构实践 - 移动-云平台\r\n福利\r\n====\r\n来个美女解解乏~嘿嘿~~\r\n![](http://bcs.duapp.com/terwer/blog/2015/03/2015-03-21_164723.jpg)\r\n
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (7392, 'schema-starting-rookie-grow-from-no-schema', '架构菜鸟成长之路之从无架构谈起:回归本质', '2015-03-20 05:39:13', '2019-03-25 23:29:05', '虽然本系列谈的是软件架构,但主要还是对B/S架构的思考。\r\n从无架构谈起\r\n============\r\nB/S从诞生到现在,已经有十几年得历史了,伴随着各种语言的兴起,框架层出不穷,本系列后续也会介绍目前常用的框架,不过作为开篇,我还是打算从无架构谈起。\r\nB/S的本质\r\n--------\r\n虽然各种框架都极力封装开简化B/S开发,但所有人都不可否认的是,B/S的本质其实就一句话:请求-响应。\r\n<img src="http://bcs.duapp.com/terwer/blog/2015/03/2015-03-20_135223.png" alt="" />\r\nB/S的特点\r\n---------\r\n优点\r\n\r\n1 具有分布性特点,可以随时进行查询、浏览等业务处理。\r\n2 业务扩展方便,通过服务器端增加程序就行。\r\n3 维护升级简单,只在服务器端更改程序。\r\n4 客户端硬件要求低。\r\n\r\n缺点\r\n\r\n1 个性化特点不明显。\r\n2 数据传输速度降低。\r\n3 服务器端负担比较重,性能要求高。\r\n4 数据安全性不如C/S架构高。\r\nB/S架构必须知道的相关网络协议及基础知识\r\n----------------------\r\n先列出几个比较常用的\r\n\r\nHTTP/HTTPS\r\n稍微了解过Web开发的都知道,http是无状态的。\r\n\r\nFTP\r\n\r\nB/S生命周期\r\n-----------\r\n从打开浏览器 输入url到你看到页面,这短暂的瞬间到底发生了什么\r\n未完待续\r\n为什么需要架构\r\n==============\r\n未完待续\r\n架构是必须的吗\r\n==============\r\n未完待续\r\n什么是好的架构\r\n==============\r\n未完待续\r\n架构是万能的吗\r\n===============\r\n未完待续\r\n\r\nB/S新的生机\r\n==========\r\nHTML5正式标准的确立以及响应式设计的概念逐渐被介绍,笔者预料,B/S开发将会迎来又一个新的春天。\r\n\r\n关于我\r\n======\r\n<img style="float:left;margin-right:20px" src="http://bcs.duapp.com/terwer/blog/2014/11/me.jpg" alt="" />\r\n装逼架构师(努力中)、业余文学爱好者。专注于项目架构、性能优化、算法研究,精通后端编程,熟练Java、.NET,目前研究Node.js。\r\n\r\n业余时间喜欢探索移动互联网开发,熟练Android。\r\n\r\n如果你也是一个热爱技术乐于分享的同道中人,可以[给我留言](http://www.terwer.com/guestbook.html) ,大家一起进步,我会抽时间尽量回复。\r\n\r\n系列导航\r\n========\r\n000 [架构菜鸟成长之路之前言](http://www.terwer.com/schema-before-rookie-growth-path.html)\r\n001 [架构菜鸟成长之路之从无架构谈起 - 回归本质](http://www.terwer.com/schema-starting-rookie-grow-from-no-schema.html)\r\n002 架构菜鸟成长之路之经典三层 - 简单封装\r\n003 架构菜鸟成长之路之四层 - 轻量级\r\n004 架构菜鸟成长之路之n层 - 重量级(IOC、AOP)\r\n005 架构菜鸟成长之路之DDD - 领域驱动设计\r\n006 架构菜鸟成长之路之SOA - 面向服务的体系结构\r\n007 架构菜鸟成长之路之OSGI - 模块化架构\r\n008 架构菜鸟成长之路之分布式 - 分布式架构\r\n009 架构菜鸟成长之路之restFul - restFul 架构\r\n。。。\r\nn 架构菜鸟成长之路之我的架构实践 - 移动-云平台\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (7505, 'csharp-empty-files', 'csharp-empty-files', '2013-03-23 13:21:07', '2019-03-25 21:29:22', '
    C#清空文件\r\n==========\r\n```\r\nFileStream fs =new FileStream(filePath,FileMode.Truncate, FileAccess.ReadWrite, FileShare.ReadWrite);\r\nStreamWriter sw = new StreamWriter(fs);\r\nsw.Write(\"\");\r\n```
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (7507, 'c-empty-files', 'C#清空文件', '2013-03-23 13:22:45', '2019-03-25 21:29:22', '
    可以用这个\r\n==========\r\n```\r\nFileStream fs =new FileStream(filePath,FileMode.Truncate, FileAccess.ReadWrite, FileShare.ReadWrite);\r\nStreamWriter sw = new StreamWriter(fs);\r\nsw.Write(\"\");\r\n```
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (7508, 'c-empty-files-2', 'C#清空文件', '2013-03-23 13:23:01', '2019-03-25 21:29:22', '
    可以用这个\r\n==========\r\n```\r\nFileStream fs =new FileStream(filePath,FileMode.Truncate, FileAccess.ReadWrite, FileShare.ReadWrite);\r\nStreamWriter sw = new StreamWriter(fs);\r\nsw.Write(\"\");\r\n```
    ', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (7509, 'datatable-by-using-the-linq-methods', 'DataTable使用LINQ的方法', '2014-12-11 04:18:09', '2019-03-25 21:29:22', ' DataTable dt=dt.Select().Where(dr =>\r\n int.Parse(dr[\"shippingid\"].ToString()) !=\r\n 1).CopyToDataTable();\r\n\r\n\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (7514, 'prepare-to-moved-to-ios', 'IOS学习笔记000:转战IOS', '2015-04-17 11:58:01', '2019-03-25 23:28:08', '准备转战IOS,先留个脚印。\r\n\r\nIOS必备书籍\r\n==========\r\n\r\n![http://www.amazon.cn/Objective-C%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1-Stephen-G-Kochan/dp/B00M21WUU8/ref=sr_1_1?ie=UTF8&qid=1429974331&sr=8-1&keywords=oc](http://ec4.images-amazon.com/images/I/51LO-cdGltL._SY344_BO1,204,203,200_.jpg)\r\nIOS论坛\r\n======\r\n中文\r\n----\r\n1.CocoaChina\r\n\r\nhttp://www.cocoachina.com/\r\n\r\n2.DevDiv\r\n\r\nhttp://www.devdiv.com/\r\n\r\n3.泰然\r\n\r\nhttp://bbs.ityran.com/forum.php\r\n\r\n4.博客园-ios区\r\n\r\nhttp://www.cnblogs.com/cate/ios/\r\n\r\n5.开源中国–ios区\r\n\r\nhttp://www.oschina.net/ios/home\r\n\r\n6.CSDN-ios区\r\n\r\nhttp://blog.csdn.net/tag/details.html?tag=iOS\r\n\r\n英文\r\n----\r\n 1.GitHub\r\n\r\nhttp://www.github.com\r\n\r\n2.Stack Overflow\r\n\r\nhttp://stackoverflow.com/\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (7519, '20150423181408', '20150423181408', '2015-04-23 10:14:09', '2019-03-25 21:29:22', '好久没有静下心来这东西了,最近好忙。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (7533, 'use-virtualbox-virtual-machine-under-win7-install-os-x-109-mavericks-and-xcode5', 'iOS学习笔记001:Win7下使用VirtualBox虚拟机安装 OS X 10.9 Mavericks 及 Xcode 5', '2015-04-26 06:36:25', '2019-03-25 23:26:36', '环境准备\r\n========\r\n电脑配置\r\n=========\r\n联想B470\r\nWindows 7, 64 bit\r\nCPU Intel Core i5\r\n内存 6GB\r\n硬盘 750GB\r\n开启虚拟化支持\r\n![](http://bcs.duapp.com/terwer/blog/2015/04/2015-04-26_145732.png)\r\n![](http://bcs.duapp.com/terwer/blog/2015/04/2015-04-26_145842.png)\r\n注意事项\r\n========\r\n由于虚拟机不支持 Apple Quartz Extreme/Core Image, 需要 Quartz Extreme 的应用软件例如 iBooks Author,Pixelmator,SketchBook 等不能在虚拟机下使用 。\r\n安装步骤\r\n========\r\n1、下载:http://pan.baidu.com/s/1hqebqYw\r\n\r\n文件 | 说明\r\n----|-----\r\nVirtualBox-4.3.6-91406-Win.exe | VirtualBox虚拟机\r\nOracle_VM_VirtualBox_Extension_Pack-4.3.6-91406.vbox-extpack | VirtualBox虚拟机扩展\r\nHackBoot_Mav.iso | 启动文件\r\nOSXMavericks2.iso | (解压 OSXMavericks2.part1.rar, OSXMavericks2.part2.rar, OSXMavericks2.part3.rar)\r\n\r\n2、双击安装 VirtualBox-4.3.6-91406-Win.exe 及 Oracle_VM_VirtualBox_Extension_Pack-4.3.6-91406.vbox-extpack\r\n\r\n3.1、 在 VirtualBOX 新建虚拟电脑\r\n\r\n名称 : Mac OS X Mavericks\r\n类型 : Mac OS X\r\n版本 : Mac OS X 10.9 Mavericks (64 bit)\r\n![](http://bcs.duapp.com/terwer/blog/2015/04/2015-04-27_002245.png)\r\n\r\n3.2、内存分配最少 2048 MB 以上\r\n![](http://bcs.duapp.com/terwer/blog/2015/04/2015-04-27_014447.png)\r\n\r\n3.3、创建新的虚拟硬盘\r\n![](http://bcs.duapp.com/terwer/blog/2015/04/2015-04-27_015444.png)\r\n\r\n3.4、选择 VDI (VirtualBox Disk Image)\r\n![](http://bcs.duapp.com/terwer/blog/2015/04/2015-04-27_015430.png)\r\n\r\n3.5、选择 Dynamically allocated\r\n![](http://bcs.duapp.com/terwer/blog/2015/04/2015-04-27_020635.png)\r\n\r\n3.6、设置虚拟硬盘位置及大小, 建议大小为 20 GB (最好 40 GB)\r\n![](http://bcs.duapp.com/terwer/blog/2015/04/2015-04-27_020911.png)\r\n\r\n4.1、打开 VirtualBOX 虚拟机的设置, 在设置的系统 -> 主板, 去掉 \"软驱\",取消勾选 \"启用 EFI\"\r\n![](http://bcs.duapp.com/terwer/blog/2015/04/2015-04-27_021547.png)\r\n\r\n4.2、系统 -> 处理器, 如果你的机器是4核,请选择双核 CPU 数量 = 2\r\n![](http://bcs.duapp.com/terwer/blog/2015/04/2015-04-27_021824.png)\r\n\r\n4.3、显示 -> 显卡 -> 显存大小设置到最大 128 MB\r\n勾选 Enable 3D Acceleration\r\n![](http://bcs.duapp.com/terwer/blog/2015/04/2015-04-27_0311411.png)\r\n\r\n5.1、在设置的 Storage -> Storage Type 属性 Controller SATA 的光盘图标 Choose a virtual CD/DVD disk file 选择```HackBoot_Mav.iso```文件\r\n![](http://bcs.duapp.com/terwer/blog/2015/04/2015-04-27_0234231.png)\r\n\r\n5.2、在 HackBoot_Mav.iso 的启动引导下, 如下 OSX Boot 页面出现后,在虚拟机菜单 CD / DVD Drive -> Choose a virtual CD/DVD disk file 选择 ```OSXMavericks2.iso```文件\r\n![](http://bcs.duapp.com/terwer/blog/2015/04/2015-04-27_0236431.png)\r\n启动过程可能停在这里一分钟\r\n![](http://bcs.duapp.com/terwer/blog/2015/04/2015-04-27_030151.png)\r\n\r\n5.3、按键 F5刷新后, 图标标签变为 OS X Base System,回车开始安装系统\r\n![](http://bcs.duapp.com/terwer/blog/2015/04/2015-04-27_030326.png)\r\n\r\n5.4、开始时, 选择安装语言\r\n![](http://bcs.duapp.com/terwer/blog/2015/04/2015-04-27_030326.png)\r\n\r\n5.5、安装系统开始时,找不到任何有效的硬盘 , 使用菜单 实用工具 ->磁盘工具 格式化虚拟硬盘\r\n![](http://bcs.duapp.com/terwer/blog/2015/04/2015-04-27_0305011.png)\r\n\r\n5.6、左边点选硬盘, 选择 \"抹掉\", 名称 Name 录入 \"Mavericks\", 然后点击 Erase 抹掉\r\n![](http://bcs.duapp.com/terwer/blog/2015/05/2015-05-07_094142.png)\r\n\r\n5.7、格式化完毕, 关闭磁盘工具后, 点选 Mavericks 磁盘, 点击 安装\r\n![](http://bcs.duapp.com/terwer/blog/2015/05/2015-05-07_094414.png)\r\n安装系统需要 30 分钟以上\r\n![](http://bcs.duapp.com/terwer/blog/2015/05/2015-05-07_0945401.png)\r\n安装 Mac OS X 系统完毕。\r\n![](http://bcs.duapp.com/terwer/blog/2015/05/2015-05-07_0945541.png)\r\n\r\n5.8、安装系统后, 需要重新启动, 虚拟机选 Close 及 Power Off 关闭虚拟机\r\n![](http://bcs.duapp.com/terwer/blog/2015/05/2015-05-07_094835.png)\r\n\r\n5.9.1、关闭 Mac OS X Mavericks 虚拟机后, 在设置的 Storage -> Storage Type Controller SATA 属性 退出 OSXMavericks2.iso\r\n![](http://bcs.duapp.com/terwer/blog/2015/05/2015-05-07_0950201.png)\r\n\r\n5.9.2、CD / DVD Drive 的光盘图标 Add CD/DVD Drive 选择 HackBoot_Mav.iso 文件\r\n![](http://bcs.duapp.com/terwer/blog/2015/05/2015-05-07_095717.png)\r\n\r\n5.10、在 HackBoot_Mav.iso 的启动引导下, 如下 OSX Boot 页面出现后\r\n![](http://bcs.duapp.com/terwer/blog/2015/05/2015-05-07_0953331.png)\r\n\r\n5.11、在虚拟机菜单 CD / DVD Drive -> Choose a virtual CD/DVD disk file 选择 OSXMavericks2.iso 文件\r\n![](http://bcs.duapp.com/terwer/blog/2015/05/2015-05-07_095840.png)\r\n\r\n5.12、按键 F5刷新后, OSX Boot 图标标签变为 OS X Base System(绿灯亮),回车再次进入安装系统\r\n![](http://bcs.duapp.com/terwer/blog/2015/05/2015-05-07_095948.png)\r\n启动过程可能停在这里一分钟\r\n![](http://bcs.duapp.com/terwer/blog/2015/05/2015-05-07_100103.png)\r\n\r\n5.13、再次进入安装系统,这次选实用工具菜单 -> 终端\r\n![](http://bcs.duapp.com/terwer/blog/2015/05/2015-05-07_100307.png)\r\n\r\n5.14、进入终端, 安装内核扩展,依次输入命令\r\n![](http://bcs.duapp.com/terwer/blog/2015/05/2015-05-07_1004541.png)\r\n\r\n5.15、依次输入命令如下:\r\n\r\n```shell\r\numount /Volumes/Mavericks\r\nhdiutil attach /dev/disk0s2 -mountpoint /Volumes/mnt\r\ncp -rp /Backup/Kexts/ElliottForceLegacyRTC.kext /Volumes/mnt/System/Library/Extensions\r\ncp -rp /Backup/Kexts/FakeSMC.kext /Volumes/mnt/System/Library/Extensions\r\ncp -rp /Backup/Kexts/NullCPUPowerManagement.kext /Volumes/mnt/System/Library/Extensions\r\nchmod -R 0755 /Volumes/mnt/System/Library/Extensions/ElliottForceLegacyRTC.kext\r\nchmod -R 0755 /Volumes/mnt/System/Library/Extensions/FakeSMC.kext\r\nchmod -R 0755 /Volumes/mnt/System/Library/Extensions/NullCPUPowerManagement.kext\r\nchown -R root:wheel /Volumes/mnt/System/Library/Extensions/ElliottForceLegacyRTC.kext\r\nchown -R root:wheel /Volumes/mnt/System/Library/Extensions/FakeSMC.kext\r\nchown -R root:wheel /Volumes/mnt/System/Library/Extensions/NullCPUPowerManagement.kext\r\nhdiutil detach /Volumes/mnt\r\n```\r\n5.16、安装内核扩展后, 退出终端后, 必须等待虚拟机的硬盘指示灯熄灭, Power Off 关闭虚拟机\r\n![](http://bcs.duapp.com/terwer/blog/2015/05/2015-05-07_100741.png)\r\n\r\n6.1、关闭 Mac OS X Mavericks 虚拟机后, 在设置的 Storage -> Storage Type Controller SATA 属性 CD / DVD Drive 的光盘图标 Add CD/DVD Drive 选择 HackBoot_Mav.iso 文件\r\n![](http://bcs.duapp.com/terwer/blog/2015/05/2015-05-07_101026.png)\r\n\r\n6.2、在 HackBoot_Mav.iso 的启动引导下, 如下 OSX Boot 页面出现后 , 使用键盘右方向键选择启动 Mavericks (绿灯亮),回车开始启动系统\r\n![](http://bcs.duapp.com/terwer/blog/2015/05/2015-05-07_1014271.png)\r\n\r\n6.3、启动 Mac OS X Mavericks 虚拟机文件后, 进入 Mac OS X 设置国家\r\n![](http://bcs.duapp.com/terwer/blog/2015/05/2015-05-07_101550.png)\r\n\r\n6.4、输入用户名称和用户初始密码\r\n![](http://bcs.duapp.com/terwer/blog/2015/05/2015-05-07_101859.png)\r\n\r\n6.5、完成其他安装步骤后,不要启动 iCloud 也不要注册, 并成功进入 Mac OS X 系统\r\n![](http://bcs.duapp.com/terwer/blog/2015/05/2015-05-07_102053.png)\r\n\r\n6.6、在 苹果菜单 -> 系统偏好设置(System Preferences) -> 安全性与隐私(Security & Privacy) 里面选择 “任何来源” (用于安装 MultiBeast)\r\n![](http://bcs.duapp.com/terwer/blog/2015/05/2015-05-07_1022391.png)\r\n\r\n6.7、使用 Mac OS X Mavericks 的 Safari\r\n下载 MultiBeast 6.1 更新 : http://pan.baidu.com/s/1sjCUOGH\r\n\r\n6.8、自动解压后的文件是在 下载 文件夹里面, 双击 MultiBeast 启动安装\r\n![](http://bcs.duapp.com/terwer/blog/2015/05/2015-05-07_103402.png)\r\n点选 Quick Start, 点选 EasyBeast\r\n![](http://bcs.duapp.com/terwer/blog/2015/05/2015-05-07_1035131.png)\r\n\r\n6.9、点选 Build 及最后点击右下角的 Install 开始安装\r\n![](http://bcs.duapp.com/terwer/blog/2015/05/2015-05-07_104421.png)\r\n\r\n6.10、等待几分钟后,安装完毕后, 在 Mac 关机。\r\n![](http://bcs.duapp.com/terwer/blog/2015/05/2015-05-07_104550.png)\r\n\r\n6.11、Mac关机及关闭 Mac OS X Mavericks 虚拟机后, 打开 VirtualBOX 设置虚拟机, 在 Storage -> Controller SATA 属性退出 HackBoot_Mav.iso 文件\r\n![](http://bcs.duapp.com/terwer/blog/2015/05/2015-05-07_104805.png)\r\n\r\n6.12、在虚拟机设置的 系统 -> 主板 勾选 \"启用 Enable EFI\"\r\n![](http://bcs.duapp.com/terwer/blog/2015/05/2015-05-07_104916.png)\r\n\r\n6.13、启动虚拟电脑, 会直接启动 Mac OS X Mavericks 虚拟硬盘, 以后并不需要 Hackboot_Mav.iso 光盘文件的引导\r\n![](http://bcs.duapp.com/terwer/blog/2015/05/2015-05-07_105053.png)\r\n\r\n7、重新启动虚拟电脑后, 可选择挂上磁盘映像 xcode_5.0.1_gm_seed.dmg 安装 Xcode 5 及 command_line_tools_os_x_mavericks_for_xcode__late_october_2013.dmg 安装 Command Line Tools\r\n![](http://bcs.duapp.com/terwer/blog/2015/05/2015-05-07_105413.png)\r\n\r\n8、使用 Mac 的终端, 取消强制 iOS 项目的签名\r\n\r\n```shell\r\nSDKFILE=\"$(xcode-select --print-path)/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.0.sdk/SDKSettings.plist\"\r\nsudo /usr/libexec/PlistBuddy -c \"Set :DefaultProperties:CODE_SIGNING_REQUIRED NO\" \"$SDKFILE\"\r\nsudo /usr/bin/plutil -convert binary1 \"$SDKFILE\"\r\n```\r\n\r\n至此,IOS开发环境全部搭建完毕。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (7633, 'objective-c-helloworld', 'iOS学习笔记002:Objective-C HelloWorld', '2015-05-07 16:39:53', '2019-03-25 21:30:44', '代码如下\r\n========\r\n```oc\r\n#import <Foundation/Foundation.h>\r\nint main(int args,const char*argv){\r\n @autoreleasepool{\r\n NSLog(@"Hello World!");\r\n }\r\n}\r\n```\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (7665, 'add-wordpress-custom-fields', 'Wordpress添加自定义字段', '2015-06-02 14:18:11', '2019-03-25 23:25:40', '最近想把文章缓存Markdown,想了很多方案,最后决定添加一个自定义字段 post_content_md\r\n其实也可以添加自定义栏目实现,但是想想,从10年到现在,到该有几千篇文章了,这么做实在是太慢,于是还是探索使用sql直接实现,代码如下:\r\n\r\ninsert into wp_postmeta(post_id,meta_key,meta_value)\r\nselect id as post_id,\'post_content_md\' as meta_key,post_content as meta_value from wp_posts\r\nwhere id not in(select post_id from wp_postmeta where meta_key=\'post_content_md\')\r\n\r\n\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (7672, 'ios-study-notes-003objective-c-object-oriented', 'iOS学习笔记003:Objective-C面向对象', '2015-06-10 10:07:48', '2019-03-25 21:30:39', 'test', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (7688, 'ios%e5%ad%a6%e4%b9%a0%e7%ac%94%e8%ae%b0004%ef%bc%9aobjective-c%e5%8f%af%e5%8f%98%e5%8f%82%e6%95%b0%e7%9a%84%e5%87%bd%e6%95%b0%e5%ae%9e%e7%8e%b0', 'iOS学习笔记004:Objective-C可变参数的函数实现', '2015-06-13 01:49:40', '2019-03-25 21:29:22', '化工部', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (7689, 'wordpress-title-optimization', 'WordPress标题优化', '2015-06-13 01:50:29', '2019-03-25 23:27:11', '原来的头部\r\n=========\r\n```php\r\n<title><?php wp_title(\'-\', true, \'right\'); echo get_option(\'blogname\'); if (is_home ()) echo get_option(\'blogdescription\'); if ($paged > 1) echo \'-Page \', $paged; ?></title>\r\n```\r\n![](http://78rdf9.com1.z0.glb.clouddn.com/2015-06-14_014616.png)\r\n\r\n修改后的头部\r\n===========\r\n```php\r\n<title>\r\n<?php wp_title(\'|\',true,\'right\'); bloginfo(\'name\');?>\r\n<?php if (is_home ()) echo \' | \', bloginfo(\'description\');?>\r\n<?php if ($paged > 1) echo \' | 第\', $paged.\'页\';?>\r\n</title>\r\n```\r\n![](http://78rdf9.com1.z0.glb.clouddn.com/2015-06-14_014627.png)', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (7799, '7144-revision-v1', '留言板', '2015-06-14 09:13:21', '2019-03-25 21:30:08', '谢谢您,您是第12696位访客。\r\n\r\n侃侃我自己\r\n=========\r\n一直以来,我都一直很难用一个固定的词语来描述我自己。或许在我的初中甚至小学同学眼里,我是一个勤奋好学,循规蹈矩的好学生;在我的高中同学眼里,我是一个埋头书海,自生自灭的梦想者;以致现在,我自诩为架构菜鸟(幻想着成为装逼架构师,呵呵),1/8文学爱好者,我的新浪博客<span style="color: #ff0000;"> **[<span style="color: #ff0000;">朝花夕拾</span>](http://blog.sina.com.cn/tyouweityouwei "朝花夕拾")**</span>(遇到过文学高手,不敢妄自称大,呵呵),至于别人怎么评价我,笔者无需过分纠结…\r\n\r\n**人生在世,有些事情,有些选择,是不需要理由的。年轻就该去探索,去尝试。人生最大的悲哀不是失败,而是甘于现状,因为他一开始就失败了。**\r\n\r\n笔者简历\r\n========\r\n\r\n2014年7月1日毕业于湖北省长江大学软件工程,在CRM客户关系管理、电子商务商城、微信商城领域有丰富的工作经验。 \r\n专注于项目架构、性能优化、算法研究。在Web开发领域有深入研究,熟练Java、.NET,目前专注于iOS开发。业余时间喜欢探索移动互联网开发,熟练Android。\r\n\r\n网站简介\r\n========\r\n网站简介\r\n特维博客(http://www.terwer.com)(原新价值网)(<a href="http://www.xinValue.Com">Www.xinValue.Com</a>)成立于2011年9月10日,先后进行了多次升级及变更,终于在2011年9月30日全新亮相!\r\n\r\n19岁萌生想法,20岁创立新价值网,面对未来,作为草根站长的我们,一切虚位以待。。。。。。\r\n\r\n特维博客(原新价值网)大事记\r\n=============================\r\n\r\n2011年9月9日-新价值网开始酝酿,采用网钛文章管理系统开始前期部署。\r\n\r\n2011年9月10日-新价值网正式上线。\r\n\r\n2011年9月11日-百度谷歌正式收录。\r\n\r\n2011年9月30日-新价值网升级完成,全新亮相,首页耳目一新,清爽简洁。\r\n\r\n2012年4月6日-域名(<a href="http://www.xinValue.Com">Ww</a><a href="http://www.xinValue.om">w.xinValue.Com</a>)顺利通过备案,正式启用域名<a href="http://www.xinvalue.com" target="_blank">Www.xinValue.Com</a>。\r\n\r\n2012年5月3日-新价值网谷歌PR值升为1。\r\n\r\n<a href="http://pr.7c.com/pr/xinvalue.com" target="_blank"><img style="border: 0px currentColor; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="pr1" src="http://whois.7c.com/images/1pr.gif" alt="pr1" width="80" height="19" /></a>\r\n\r\n2012年11月24日-新价值网转移到织梦DedeCMS,开始新的探索。\r\n\r\n<span style="color: #ff0000;"><strong>2013年7月2日,新价值网转战Wordpress,新起点,新跨越!</strong></span>\r\n\r\n2013年10月17日,新价值网推出<a href="http://www.wumii.com/auto_app/download/Zah85q" target="_blank">iphone客户端和Android客户端</a>。\r\n\r\n<a href="http://www.wumii.com/auto_app/download/Zah85q"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="client" src="http://bcs.duapp.com/terwer/blog/2013/10/client1.gif" alt="client" width="348" height="669" border="0" /></a>\r\n\r\n<strong><span style="color: #ff0000;">2013年11月23日,新价值网搜索(<a href="http://search.xinvalue.com" target="_blank">http://Search.xinValue.Com</a>)上线,支持本博客站内搜索,关键字自动完成,全网视频搜索及无广告在线观看。</span></strong>\r\n\r\n2013年12月17日,心情随笔上线(<a href="http://Www.xinValue.Com/diary" target="_blank">http://Www.xinValue.Com/diary</a>)。\r\n\r\n2013年12月23日,新价值网推出影视网站:纯纯影视(<a href="http://tvnoad.com" target="_blank">http://tvnoad.com</a>)。\r\n\r\n<span style="color: #ff0000;"><strong>2013年12月24日,新价值网谷歌PR值升为2。</strong></span>\r\n\r\n<a href="http://pr.7c.com/pr/xinvalue.com" target="_blank"><img src="http://whois.7c.com/images/2pr.gif" alt="pr2" width="80" height="19" /></a>\r\n\r\n<span style="font-size: 24pt;"><strong style="color: #ff0000;">2014年8月24日,新价值网更新为特维博客,域</strong></span>\r\n\r\n<span style="font-size: 24pt;"><strong style="color: #ff0000;">名更换为:http://www.terwer.com。</strong></span>\r\n\r\n2015年06月14日,全新主题Terwer1.0。\r\n\r\n笔者的联系方式\r\n==============\r\nQQ:<a href="http://wpa.qq.com/msgrd?v=3&uin=1035136784&site=qq&menu=yes"><img style="display:inline;" src="http://wpa.qq.com/pa?p=2:1035136784:41%20&r=0.4180186064662228" alt="点击这里给我发消息" title="点击这里给我发消息"/></a>\r\n微博:[@LeaveBugsAway](http://weibo.com/tyouwei)\r\n邮箱:[cbgtyw@gmail.com](mailto:cbgty@gmail.com) ', 1, 0, NULL, NULL, 'inherit', 'revision', 1, 0); +INSERT INTO `posts` VALUES (7844, 'sample-page', '示例页面', '2015-06-12 22:00:03', '2019-03-25 23:27:30', '这是示范页面。页面和博客文章不同,它的位置是固定的,通常会在站点导航栏显示。很多用户都创建一个“关于”页面,向访客介绍自己。例如,个人博客通常有类似这样的介绍:\r\n\r\n
    欢迎!我白天是个邮递员,晚上就是个有抱负的演员。这是我的博客。我住在天朝的帝都,有条叫做杰克的狗。
    \r\n\r\n……公司博客可以这样写:\r\n\r\n
    XYZ Doohickey公司成立于1971年,自从建立以来,我们一直向社会贡献着优秀doohicky。我们的公司总部位于天朝魔都,有着超过两千名员工,对魔都政府税收有着巨大贡献。
    \r\n\r\n您可以访问仪表盘,删除本页面,然后添加您自己的内容。祝您使用愉快!', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (7846, '', 'Docker创建CentOS7.6', '2019-03-26 00:53:46', '2019-09-10 13:27:19', '# 拉取Docker镜像\r\n\r\n```bash\r\ndocker pull centos:centos7.6.1810\r\n```\r\n\r\n日志\r\n\r\n```\r\nPS C:\\Users\\Terwer> docker pull centos:centos7.6.1810\r\ncentos7.6.1810: Pulling from library/centos\r\nac9208207ada: Pull complete\r\nDigest: sha256:6ae4cddb2b37f889afd576a17a5286b311dcbf10a904409670827f6f9b50065e\r\nStatus: Downloaded newer image for centos:centos7.6.1810\r\n```\r\n\r\n# 运行CentOS容器\r\n\r\n## 临时运行\r\n\r\n退出后会清空容器\r\n\r\n\r\n```bash\r\ndocker run -it --rm centos:centos7.6.1810 bash\r\n```\r\n\r\n## 持久运行容器\r\n\r\n```bash\r\ndocker run -i -t --name mycentos centos:centos7.6.1810 /bin/bash\r\n```\r\n\r\n查看容器运行状态\r\n\r\n```\r\ndocker ps -a\r\n```\r\n\r\n查看镜像\r\n\r\n```\r\ndocker images\r\n```\r\n\r\n# 启动容器\r\n\r\n```\r\ndocker start mycentos\r\n```\r\n\r\n自动重启\r\n\r\n```\r\ndocker run --restart=always --name mycentos -d centos /bin/sh -c \"while true;do echo hello world; sleep;done\"\r\n```\r\n\r\n# 停止容器\r\n\r\n```\r\ndocker stop mycentos\r\n```\r\n\r\n## 退出容器\r\n\r\n`Ctrl+D` 或者 `exit`\r\n\r\n# 删除容器\r\n\r\n```\r\ndocker rm mycentos\r\n```\r\n\r\n# 删除镜像\r\n\r\n```\r\ndocker rmi f1cb7c7d58b7\r\n```', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7847, '', 'Docker开启CentOS的SSH', '2019-03-26 01:53:52', '2019-11-27 22:29:29', '# 拉取镜像\r\n\r\n```\r\n docker pull jdeathe/centos-ssh:centos-7\r\n```\r\n\r\n# 运行\r\n\r\n```\r\ndocker run -d --name my-ssh-centos -p 2020:22 jdeathe/centos-ssh:centos-7\r\n```\r\n\r\n# 修改root密码\r\n\r\n```\r\ndocker exec -it my-ssh-centos bash\r\npasswd\r\n```\r\n\r\n# 链接\r\n\r\n## 下载密钥\r\n\r\n```\r\ncurl -LSs https://raw.githubusercontent.com/mitchellh/vagrant/master/keys/vagrant > id_rsa_insecure\r\n```\r\n\r\n## 使用密钥链接\r\n\r\n```\r\nssh -p 2020 -i id_rsa_insecure app-admin@127.0.0.1\r\n```\r\n\r\n# 安装neofetch\r\n\r\n```\r\nhttps://github.com/dylanaraps/neofetch/wiki/Installation#fedora--rhel--centos--mageia\r\n```', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7848, '', 'JAVA虚拟机学习笔记(一)编译OpenJDK8或者dragonwell8', '2019-03-27 07:41:10', '2019-11-29 01:53:47', '# 编译环境的准备\r\n## JDK源码下载\r\n\r\n### OpenJDK\r\n\r\nhttp://jdk.java.net/java-se-ri/8\r\n\r\n下载地址\r\n\r\n```bash\r\nhttps://download.java.net/openjdk/jdk8u40/ri/openjdk-8u40-src-b25-10_feb_2015.zip\r\n```\r\n\r\n### dragonwell8\r\n\r\nhttps://github.com/alibaba/dragonwell8\r\n\r\n## 准备编译环境\r\n\r\n解压下载的压缩包,进入文件夹,点击README-builds.html,这是官方给的编译指导手册。\r\n\r\n> 支持的环境\r\n\r\n```bash\r\nhttps://wiki.openjdk.java.net/display/Build/Supported+Build+Platforms\r\n```\r\n\r\n### fedora29\r\n\r\n最好选择fedora29\r\n\r\n![](https://terwer.oss-cn-qingdao.aliyuncs.com/bugucms/20190327123104.jpg)\r\n\r\n下载地址\r\n\r\n```bash\r\nhttps://archives.fedoraproject.org/pub/archive/fedora/linux/releases/9/Fedora/x86_64/iso/\r\n```\r\n\r\n### ubuntu14\r\n\r\n如果使用图形界面,建议选择 `ubuntu-14.04.6-desktop`\r\n\r\n#### 下载地址\r\n\r\n```\r\nhttp://releases.ubuntu.com/14.04/ubuntu-14.04.6-desktop-amd64.iso\r\n```\r\n\r\n#### 安装Boot JDK\r\n\r\n安装``Boot JDK``,编译``OpenJDK8``最好选择``jdk1.7``\r\n\r\n\r\n```\r\nhttps://www.oracle.com/technetwork/java/javase/downloads/java-archive-downloads-javase7-521261.html\r\n```\r\n\r\nor\r\n\r\n```\r\nwget https://terwer.oss-cn-qingdao.aliyuncs.com/soft/jdk/jdk-7u80-linux-x64.tar.gz\r\n```\r\n\r\n#### 安装依赖库\r\n\r\n\r\n```\r\nsudo apt-get install libx11-dev libxext-dev libxrender-dev libxtst-dev libxt-dev libcups2-dev libfreetype6-dev libasound2-dev -y\r\nsudo apt-get install build-essential -y\r\n```\r\n\r\n#### 安装ccache高速编译工具\r\n\r\n在处理一些规模相对较大的工程时,编译花费的时间可能会很长。有时候我们会经常一遍一遍地编译相同的程序,此时,有了ccache情况就好多了。它将在第一遍编译时多花几秒钟,但接下来就会使编译成倍(5-10倍)的提速。\r\n\r\nccache 的基本原理是通过将头文件高速缓存到源文件之中而改进了构建性能,因而通过减少每一步编译时添加头文件所需要的时间而提高了构建速度。以下来了解下如何同时使用 ccache 和distcc 来使开发环境达到最佳性能。\r\n\r\n```\r\nsudo apt install ccache -y\r\n```\r\n\r\n### wsl\r\n\r\n配置gcc为4.8\r\n\r\nhttp://www.terwergreen.com/post-dark/7866.html\r\n# 开始编译\r\n## CentOS/fedora29\r\n\r\n```\r\n./configure --with-boot-jdk=/opt/java/jdk1.7.0_80 --with-debug-level=slowdebug --with-native-debug-symbols=internal --with-jvm-variants=server --with-target-bits=64 --with-num-cores=4\r\n```\r\n\r\n## Wlinux/ubuntu14\r\n\r\n\r\n### 配置构建\r\n\r\n#### ubuntu14\r\n\r\ndragonwell8\r\n```\r\n./configure --with-boot-jdk=/opt/java/jdk1.7.0_80 --with-freetype-include=/usr/include/freetype2 --with-freetype-lib=/usr/lib/x86_64-linux-gnu --with-debug-level=slowdebug --with-native-debug-symbols=internal --with-jvm-variants=server --with-target-bits=64 --enable-ccache --with-num-cores=4 --with-memory-size=3000\r\n```\r\n\r\nopenjdk\r\n\r\n```bash\r\nsudo chmod +x ./configure\r\n\r\n./configure --with-boot-jdk=/opt/java/jdk1.7.0_80 --with-freetype-include=/usr/include/freetype2 --with-freetype-lib=/usr/lib/x86_64-linux-gnu --with-debug-level=slowdebug --with-jvm-variants=server --with-target-bits=64 --enable-ccache --with-num-cores=4 --with-memory-size=3000\r\n```\r\n\r\nlog\r\n\r\n```\r\n====================================================\r\nA new configuration has been successfully created in\r\n/home/terwer/workspace/dragonwell8/build/linux-x86_64-normal-server-slowdebug\r\nusing configure arguments \'--with-boot-jdk=/opt/java/jdk1.7.0_80 --with-debug-level=slowdebug --with-jvm-variants=server --with-target-bits=64 --enable-ccache --with-num-cores=4 --with-memory-size=3000\'.\r\n\r\nConfiguration summary:\r\n* Debug level: slowdebug\r\n* JDK variant: normal\r\n* JVM variants: server\r\n* OpenJDK target: OS: linux, CPU architecture: x86, address length: 64\r\n\r\nTools summary:\r\n* Boot JDK: java version \"1.7.0_80\" Java(TM) SE Runtime Environment (build 1.7.0_80-b15) Java HotSpot(TM) 64-Bit Server VM (build 24.80-b11, mixed mode) (at /opt/java/jdk1.7.0_80)\r\n* Toolchain: gcc (GNU Compiler Collection)\r\n* C Compiler: Version 4.8.4 (at /usr/bin/gcc)\r\n* C++ Compiler: Version 4.8.4 (at /usr/bin/g++)\r\n\r\nBuild performance summary:\r\n* Cores to use: 2\r\n* Memory limit: 3000 MB\r\n* ccache status: enabled\r\n```\r\n\r\nbuild images log\r\n\r\n```\r\n## Finished images (build time 00:03:19)\r\n\r\n----- Build times -------\r\nStart 2019-03-29 16:02:40\r\nEnd 2019-03-29 19:11:11\r\n00:04:57 corba\r\n00:03:48 demos\r\n02:19:09 hotspot\r\n00:03:19 images\r\n00:03:18 jaxp\r\n00:04:15 jaxws\r\n00:23:26 jdk\r\n00:04:34 langtools\r\n00:01:44 nashorn\r\n03:08:31 TOTAL\r\n-------------------------\r\nFinished building OpenJDK for target \'images\'\r\n```\r\n\r\n#### wsl\r\n\r\nunset JAVA_HOME\r\n\r\ndragonwell8\r\n```\r\n ./configure --with-boot-jdk=/opt/java/jdk1.7.0_80 --with-freetype-include=/usr/include/freetype2 --with-freetype-lib=/usr/lib/x86_64-linux-gnu --with-debug-level=slowdebug --with-native-debug-symbols=internal --with-jvm-variants=server --with-target-bits=64\r\n```\r\n\r\nopenjdk\r\n```\r\nsudo chmod +x ./configure\r\n\r\n./configure --with-boot-jdk=/opt/java/jdk1.7.0_80 --with-freetype-include=/usr/include/freetype2 --with-freetype-lib=/usr/lib/x86_64-linux-gnu --with-debug-level=slowdebug --with-jvm-variants=server --with-target-bits=64\r\n```\r\n\r\nlog\r\n\r\n```\r\n====================================================\r\nA new configuration has been successfully created in\r\n/mnt/c/Users/Terwer/WSLProjects/dragonwell8/build/linux-x86_64-normal-server-slowdebug\r\nusing configure arguments \'--with-boot-jdk=/opt/java/jdk1.7.0_80 --with-freetype-include=/usr/include/freetype2 --with-freetype-lib=/usr/lib/x86_64-linux-gnu --with-debug-level=slowdebug --with-native-debug-symbols=internal --with-jvm-variants=server --with-target-bits=64\'.\r\n\r\nConfiguration summary:\r\n* Debug level: slowdebug\r\n* JDK variant: normal\r\n* JVM variants: server\r\n* OpenJDK target: OS: linux, CPU architecture: x86, address length: 64\r\n\r\nTools summary:\r\n* Boot JDK: java version \"1.7.0_80\" Java(TM) SE Runtime Environment (build 1.7.0_80-b15) Java HotSpot(TM) 64-Bit Server VM (build 24.80-b11, mixed mode) (at /opt/java/jdk1.7.0_80)\r\n* Toolchain: gcc (GNU Compiler Collection)\r\n* C Compiler: Version 4.8.5 (at /usr/bin/gcc)\r\n* C++ Compiler: Version 4.8.5 (at /usr/bin/g++)\r\n\r\nBuild performance summary:\r\n* Cores to use: 4\r\n* Memory limit: 8142 MB\r\n\r\nWARNING: Your build output directory is not on a local disk.\r\nThis will severely degrade build performance!\r\nIt is recommended that you create an output directory on a local disk,\r\nand run the configure script again from that directory.\r\n```\r\n\r\n### 构建\r\n\r\n#### only image\r\n\r\n```\r\nsudo make images\r\n```\r\n\r\nor\r\n\r\n```\r\nterwer@ubuntu-work:~/workspace/dragonwell8$ sudo make images\r\nNo CONF given, but more than one configuration found in /home/terwer/workspace/dragonwell8//build.\r\nAvailable configurations:\r\n* linux-x86_64-normal-server-release\r\n* linux-x86_64-normal-server-slowdebug\r\nPlease retry building with CONF= (or SPEC=)\r\nMakefile:55: *** Cannot continue. Stop.\r\nterwer@ubuntu-work:~/workspace/dragonwell8$ sudo make images CONF=linux-x86_64-normal-server-slowdebug\r\n```\r\n\r\nlog\r\n\r\n```\r\nBuilding \'linux-x86_64-normal-server-slowdebug\' (matching CONF=linux-x86_64-normal-server-slowdebug)\r\nBuilding OpenJDK for target \'images\' in configuration \'linux-x86_64-normal-server-slowdebug\'\r\n```\r\n\r\n#### build all\r\n\r\n```\r\nsudo build all\r\n```\r\n# 问题处理\r\n\r\n## WSL的WLinux问题\r\n\r\n> ` This OS is not supported: Linux WORK 4.4.0-17134-Microsoft #648-Microsoft Tue Mar 05 18:57:00 PST 2019 x86_64 GNU/Linux`\r\n\r\n解决\r\n\r\n```\r\n# 修改文件 ./hotspot/make/linux/Makefile\r\n# 修改 SUPPORTED_OS_VERSION = 2.4% 2.5% 2.6% 2.7% 为 \r\nSUPPORTED_OS_VERSION = 2.4% 2.5% 2.6% 2.7% 3% 4%\r\n```\r\n\r\n> `configure: error: Could not find freetype! You might be able to fix this by running \'sudo apt-get install libfreetype6-dev\'.\r\nconfigure exiting with result code 1`\r\n\r\n\r\n解决\r\n\r\n```\r\n./configure --with-freetype-include=/usr/include/freetype2 --with-freetype-lib=/usr/lib/x86_64-linux-gnu\r\n```\r\n\r\n> `Generating precompiled header precompiled.hpp.gch\r\nIn file included from /mnt/c/Users/Terwer/WSLProjects/openjdk/hotspot/src/share/vm/memory/sharedHeap.hpp:29:0,\r\n from /mnt/c/Users/Terwer/WSLProjects/openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelComp\r\nact.hpp:34,\r\n from /mnt/c/Users/Terwer/WSLProjects/openjdk/hotspot/src/share/vm/gc_implementation/shared/markSweep.inline.hpp:34,\r\n from /mnt/c/Users/Terwer/WSLProjects/openjdk/hotspot/src/share/vm/oops/oop.inline.hpp:29,\r\n from /mnt/c/Users/Terwer/WSLProjects/openjdk/hotspot/src/share/vm/classfile/classFileParser.hpp:30,\r\n from /mnt/c/Users/Terwer/WSLProjects/openjdk/hotspot/src/share/vm/classfile/classLoader.hpp:28,\r\n from /mnt/c/Users/Terwer/WSLProjects/openjdk/hotspot/src/share/vm/classfile/systemDictionary.hpp:29,\r\n from /mnt/c/Users/Terwer/WSLProjects/openjdk/hotspot/src/share/vm/ci/ciEnv.hpp:30,\r\n from /mnt/c/Users/Terwer/WSLProjects/openjdk/hotspot/src/share/vm/ci/ciUtilities.hpp:28,\r\n from /mnt/c/Users/Terwer/WSLProjects/openjdk/hotspot/src/share/vm/ci/ciNullObject.hpp:30,\r\n from /mnt/c/Users/Terwer/WSLProjects/openjdk/hotspot/src/share/vm/ci/ciConstant.hpp:29,\r\n from /mnt/c/Users/Terwer/WSLProjects/openjdk/hotspot/src/share/vm/ci/ciArray.hpp:29,\r\n from /mnt/c/Users/Terwer/WSLProjects/openjdk/hotspot/src/share/vm/precompiled/precompiled.hpp:33:\r\n/mnt/c/Users/Terwer/WSLProjects/openjdk/hotspot/src/share/vm/memory/generation.hpp:425:17: warning: invalid suffix on literal; C++11\r\n requires a space between literal and string macro [-Wliteral-suffix]\r\n warning(\"time warp: \"INT64_FORMAT\" to \"INT64_FORMAT, (int64_t)_time_of_last_gc, (int64_t)now);\r\n ^\r\n/mnt/c/Users/Terwer/WSLProjects/openjdk/hotspot/src/share/vm/memory/generation.hpp:425:42: warning: invalid suffix on literal; C++11\r\n requires a space between literal and string macro [-Wliteral-suffix]\r\n warning(\"time warp: \"INT64_FORMAT\" to \"INT64_FORMAT, (int64_t)_time_of_last_gc, (int64_t)now);\r\n ^\r\nIn file included from /mnt/c/Users/Terwer/WSLProjects/openjdk/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp:30:0,\r\n from /mnt/c/Users/Terwer/WSLProjects/openjdk/hotspot/src/share/vm/oops/oop.inline.hpp:30,\r\n from /mnt/c/Users/Terwer/WSLProjects/openjdk/hotspot/src/share/vm/classfile/classFileParser.hpp:30,\r\n from /mnt/c/Users/Terwer/WSLProjects/openjdk/hotspot/src/share/vm/classfile/classLoader.hpp:28,\r\n from /mnt/c/Users/Terwer/WSLProjects/openjdk/hotspot/src/share/vm/classfile/systemDictionary.hpp:29,\r\n from /mnt/c/Users/Terwer/WSLProjects/openjdk/hotspot/src/share/vm/ci/ciEnv.hpp:30,\r\n from /mnt/c/Users/Terwer/WSLProjects/openjdk/hotspot/src/share/vm/ci/ciUtilities.hpp:28,\r\n from /mnt/c/Users/Terwer/WSLProjects/openjdk/hotspot/src/share/vm/ci/ciNullObject.hpp:30,\r\n from /mnt/c/Users/Terwer/WSLProjects/openjdk/hotspot/src/share/vm/ci/ciConstant.hpp:29,\r\n from /mnt/c/Users/Terwer/WSLProjects/openjdk/hotspot/src/share/vm/ci/ciArray.hpp:29,\r\n from /mnt/c/Users/Terwer/WSLProjects/openjdk/hotspot/src/share/vm/precompiled/precompiled.hpp:33:\r\n/mnt/c/Users/Terwer/WSLProjects/openjdk/hotspot/src/share/vm/memory/threadLocalAllocBuffer.inline.hpp:97:25: warning: invalid suffix\r\n on literal; C++11 requires a space between literal and string macro [-Wliteral-suffix]\r\n gclog_or_tty->print(\"TLAB: %s thread: \"INTPTR_FORMAT\" [id: %2d]\"\r\n ^\r\n/mnt/c/Users/Terwer/WSLProjects/openjdk/hotspot/src/share/vm/memory/threadLocalAllocBuffer.inline.hpp:98:25: warning: invalid suffix\r\n on literal; C++11 requires a space between literal and string macro [-Wliteral-suffix]\r\n`\r\n\r\n解决\r\n\r\n在文件 `./hotspot/make/linux/makefiles/gcc.make` 修改下面的代码\r\n\r\n```\r\n# Compiler warnings are treated as errors\r\n# WARNINGS_ARE_ERRORS = -Werror\r\nWARNINGS_ARE_ERRORS = -Wno-all\r\n```\r\n\r\n`error: left operand of shift expression ‘(-1 << 28)’ is negative [-fpermissive]`\r\n\r\n解决\r\n\r\n```\r\n#add by Kun\r\nCFLAGS += -fpermissive\r\n#end\r\n```\r\n\r\n## ubuntu14编译报错\r\n\r\n```bash\r\nCompiling /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/jni/jfrGetAllEventClasses.cpp\r\nCompiling /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/jni/jfrJavaCall.cpp\r\nCompiling /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/writers/jfrJavaEventWriter.cpp\r\nCompiling /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/utilities/jfrJavaLog.cpp\r\n/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/utilities/jfrJavaLog.cpp: In static member function ‘static void JfrJavaLog::log(jint, jint, jstring, Thread*)’:\r\n/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/utilities/jfrJavaLog.cpp:47:21: error: format not a string literal and no format arguments [-Werror=format-security]\r\n log_trace(jfr)(s);\r\n ^\r\n/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/utilities/jfrJavaLog.cpp:50:21: error: format not a string literal and no format arguments [-Werror=format-security]\r\n log_debug(jfr)(s);\r\n ^\r\n/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/utilities/jfrJavaLog.cpp:53:20: error: format not a string literal and no format arguments [-Werror=format-security]\r\n log_info(jfr)(s);\r\n ^\r\n/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/utilities/jfrJavaLog.cpp:56:23: error: format not a string literal and no format arguments [-Werror=format-security]\r\n log_warning(jfr)(s);\r\n ^\r\n/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/utilities/jfrJavaLog.cpp:59:21: error: format not a string literal and no format arguments [-Werror=format-security]\r\n log_error(jfr)(s);\r\n ^\r\ncc1plus: all warnings being treated as errors\r\nmake[6]: *** [jfrJavaLog.o] Error 1\r\nmake[5]: *** [the_vm] Error 2\r\nmake[4]: *** [product] Error 2\r\nmake[3]: *** [generic_build2] Error 2\r\nmake[2]: *** [product] Error 2\r\nmake[1]: *** [/home/terwer/workspace/dragonwell8/build/linux-x86_64-normal-server-release/hotspot/_hotspot.timestamp] Error 2\r\nmake: *** [hotspot-only] Error 2\r\nterwer@ubuntu:~/workspace/dragonwell8$ \r\n```\r\n\r\n解决\r\n\r\n在文件 `./hotspot/make/linux/makefiles/gcc.make` 修改下面的代码\r\n\r\n```\r\n# Compiler warnings are treated as errors\r\n# WARNINGS_ARE_ERRORS = -Werror\r\nWARNINGS_ARE_ERRORS = -Wno-all\r\n```\r\n\r\n# 构建成功\r\n![](https://terwer.oss-cn-qingdao.aliyuncs.com/bugucms/20190329123502.png)\r\n\r\n```\r\n----- Build times -------\r\nStart 2019-03-29 10:55:48\r\nEnd 2019-03-29 12:31:27\r\n00:03:25 corba\r\n00:03:20 demos\r\n00:18:37 docs\r\n00:35:29 hotspot\r\n00:03:31 images\r\n00:02:21 jaxp\r\n00:04:19 jaxws\r\n00:22:28 jdk\r\n00:00:00 langtools\r\n00:02:08 nashorn\r\n01:35:39 TOTAL\r\n-------------------------\r\nFinished building OpenJDK for target \'all\'\r\n```\r\n\r\n# 验证\r\nubuntu 14 右键打开终端\r\n\r\n```\r\nsudo apt-get install nautilus-open-terminal -y\r\nnautilis -q\r\n```\r\n\r\n验证java编译结果\r\n\r\n```bash\r\nterwer@ubuntu-work:~/workspace/dragonwell8/build/linux-x86_64-normal-server-release/jdk/bin$ ./java -version\r\nopenjdk version \"1.8.0-internal\"\r\nOpenJDK Runtime Environment ( ) (build 1.8.0-internal-root_2019_03_29_09_33-b00)\r\nOpenJDK 64-Bit Server VM ( ) (build 25.71-b00, mixed mode)\r\n```\r\n\r\n# 附\r\n\r\n## Java SE规范\r\n\r\n[https://docs.oracle.com/javase/specs/index.html](https://docs.oracle.com/javase/specs/index.html)', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (7849, '', 'WIN10与Virtualbox里面的linux共享文件夹', '2019-03-28 00:23:44', '2019-11-30 19:25:41', '# Install the packages required\r\n\r\n## fedora\r\n```\r\nyum update\r\nyum install gcc kernel-devel make -y\r\n\r\nreboot\r\n```\r\n## ubuntu\r\n```\r\nsudo apt update\r\nsudo apt upgrade\r\nsudo apt install dkms build-essential virtualbox-guest-x11 linux-headers-generic linux-headers-virtual -y\r\n```\r\n\r\n# Install Guest Additions via a Terminal\r\n## fedora\r\n```\r\nmount -r /dev/cdrom /media\r\ncd /media/\r\n./VBoxLinuxAdditions.run \r\n```\r\n\r\n日志\r\n\r\n```\r\nVerifying archive integrity... All good.\r\nUncompressing VirtualBox 6.0.4 Guest Additions for Linux........\r\nVirtualBox Guest Additions installer\r\nCopying additional installer modules ...\r\nInstalling additional modules ...\r\nVirtualBox Guest Additions: Building the VirtualBox Guest Additions kernel\r\nmodules. This may take a while.\r\nVirtualBox Guest Additions: To build modules for other installed kernels, run\r\nVirtualBox Guest Additions: /sbin/rcvboxadd quicksetup \r\nVirtualBox Guest Additions: Kernel headers not found for target kernel\r\n2.6.25-14.fc9.x86_64. Please install them and execute\r\n /sbin/rcvboxadd setup\r\nVirtualBox Guest Additions: Starting.\r\n```\r\n## ubuntu\r\n```\r\nsudo mount -r /dev/cdrom /media/cdrom\r\ncd /media/cdrom\r\nsudo ./VBoxLinuxAdditions.run \r\n```\r\n\r\n# 重启\r\n\r\n```\r\nreboot\r\n```\r\n\r\n# 挂载共享文件夹\r\n\r\n## Windows设置\r\n\r\n![](https://terwer.oss-cn-qingdao.aliyuncs.com/bugucms/20190327162611.png)\r\n\r\n\r\n共享文件夹名称:`fedora_share`\r\n\r\n挂载点:`/mnt/fedora`\r\n\r\n\r\n## 挂载\r\n### fedora\r\n\r\n```\r\nmkdir /mnt/fedora\r\nmount -t vboxsf fedora_share /mnt/fedora\r\n```\r\n\r\n### ubuntu\r\n```\r\nsudo mount -t vboxsf ubuntu_share /mnt/ubuntu\r\n```', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7850, '', 'JAVA虚拟机学习笔记(三)CentOS7下CLion调试dragonwell8源码', '2019-03-29 22:07:49', '2019-09-01 10:02:01', '> 2019/04/13 验证通过 \r\n> \r\n# 安装CLion\r\n\r\n```\r\nhttps://download.jetbrains.8686c.com/cpp/CLion-2019.1.tar.gz\r\n```\r\n\r\n# 使用clion载入源码\r\n\r\n首先,我们打开clion,选择 `File->New CMake Project from sources...`,选择到 `~/workspace/dragonwell8/hotspot` 作为jvm源码的根目录,点击next即可。\r\n\r\n# 创建 CMakeLists.txt\r\n\r\n```\r\ncmake_minimum_required(VERSION 3.13)\r\nproject(hotspot)\r\n\r\ninclude_directories(\r\n src/share/vm\r\n src/os/linux/vm\r\n src/cpu/x86/vm\r\n src/os_cpu/linux_x86/vm\r\n src/share/vm/precompiled)\r\n\r\nfile(GLOB_RECURSE SOURCE_FILES \"*.cpp\" \"*.hpp\" \"*.c\" \"*.h\")\r\nadd_executable(hotspot ${SOURCE_FILES})\r\n```\r\n\r\n# 调试 HotSpot源码\r\n\r\n参数输入 `-version`\r\n\r\n```\r\n/home/terwer/workspace/dragonwell8/build/linux-x86_64-normal-server-slowdebug/images/j2sdk-image/bin/java -version\r\nopenjdk version \"1.8.0_202-debug\"\r\nOpenJDK Runtime Environment (Dragonwell-Terwer 8.0-preview) (build 1.8.0_202-debug-b00)\r\nOpenJDK 64-Bit Server VM (Dragonwell-Terwer 8.0-preview) (build 25.202-b00-debug, mixed mode)\r\n```\r\n\r\n接下来我们调试 HotSpot,在hotspot目录下的jni.cpp中找到 JNI_CreateJavaVM\r\n\r\n```\r\n/Users/alberthumbert/jdk7u-dev/hotspot/src/share/vm/prims/jni.cpp\r\n```\r\n随便打上断点,如果你上一步已经成功,那么现在所有的配置参数都不需要改变,直接调试即可。\r\n\r\n**现在,即可开始你的深入理解 java 虚拟机之旅!**\r\n\r\n![](https://terwer.oss-cn-qingdao.aliyuncs.com/bugucms/20190413160003.png)\r\n\r\n# 错误解决\r\n\r\n```\r\nCannot get compiler information:\r\n Compiler exited with error code 1: /usr/bin/cc -xobjective-c -I/home/terwer/workspace/dragonwell8/hotspot/agent/src/os/bsd -I/home/terwer/workspace/dragonwell8/hotspot/agent/src/os/linux -I/home/terwer/workspace/dragonwell8/hotspot/agent/src/os/solaris/proc -I/home/terwer/workspace/dragonwell8/hotspot/src/cpu/ppc/vm -I/home/terwer/workspace/dragonwell8/hotspot/src/cpu/sparc/vm -I/home/terwer/workspace/dragonwell8/hotspot/src/cpu/x86/vm -I/home/terwer/workspace/dragonwell8/hotspot/src/cpu/zero/vm -I/home/terwer/workspace/dragonwell8/hotspot/src/os/aix/vm -I/home/terwer/workspace/dragonwell8/hotspot/src/os/bsd/dtrace -I/home/terwer/workspace/dragonwell8/hotspot/src/os/bsd/vm -I/home/terwer/workspace/dragonwell8/hotspot/src/os/linux/vm -I/home/terwer/workspace/dragonwell8/hotspot/src/os/posix/vm -I/home/terwer/workspace/dragonwell8/hotspot/src/os/solaris/dtrace -I/home/terwer/workspace/dragonwell8/hotspot/src/os/solaris/vm -I/home/terwer/workspace/dragonwell8/hotspot/src/os/windows/vm -I/home/terwer/workspace/dragonwell8/hotspot/src/os_cpu/aix_ppc/vm -I/home/terwer/workspace/dragonwell8/hotspot/src/os_cpu/bsd_x86/vm -I/home/terwer/workspace/dragonwell8/hotspot/src/os_cpu/bsd_zero/vm -I/home/terwer/workspace/dragonwell8/hotspot/src/os_cpu/linux_ppc/vm -I/home/terwer/workspace/dragonwell8/hotspot/src/os_cpu/linux_sparc/vm -I/home/terwer/workspace/dragonwell8/hotspot/src/os_cpu/linux_x86/vm -I/home/terwer/workspace/dragonwell8/hotspot/src/os_cpu/linux_zero/vm -I/home/terwer/workspace/dragonwell8/hotspot/src/os_cpu/solaris_sparc/vm -I/home/terwer/workspace/dragonwell8/hotspot/src/os_cpu/solaris_x86/vm -I/home/terwer/workspace/dragonwell8/hotspot/src/os_cpu/windows_x86/vm -I/home/terwer/workspace/dragonwell8/hotspot/src/share/tools/hsdis -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/adlc -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/asm -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/c1 -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/ci -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/classfile -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/code -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/compiler -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/gc_implementation/g1 -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/gc_implementation/parallelScavenge -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/gc_implementation/parNew -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/gc_implementation/shared -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/gc_interface -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/interpreter -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/dcmd -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/instrumentation -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/jni -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/leakprofiler -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/leakprofiler/chains -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/leakprofiler/checkpoint -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/leakprofiler/sampling -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/leakprofiler/utilities -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/metadata -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/periodic -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/periodic/sampling -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/recorder -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/recorder/access -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/recorder/checkpoint -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/recorder/checkpoint/constant -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/recorder/checkpoint/constant/traceid -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/recorder/repository -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/recorder/service -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/recorder/stacktrace -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/recorder/storage -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/recorder/stringpool -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/utilities -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/writers -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jwarmup -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/libadt -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/memory -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/oops -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/opto -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/precompiled -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/prims -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/prims/wbtestmethods -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/runtime -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/services -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/shark -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/trace -I/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/utilities -I/home/terwer/workspace/dragonwell8/hotspot/test/jfr -g -fpch-preprocess -v -dD -E\r\n Using built-in specs.\r\n COLLECT_GCC=/usr/bin/cc\r\n Target: x86_64-redhat-linux\r\n Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/cloog-install --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux\r\n Thread model: posix\r\n gcc version 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC) \r\n COLLECT_GCC_OPTIONS=\'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/agent/src/os/bsd\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/agent/src/os/linux\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/agent/src/os/solaris/proc\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/cpu/ppc/vm\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/cpu/sparc/vm\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/cpu/x86/vm\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/cpu/zero/vm\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/os/aix/vm\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/os/bsd/dtrace\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/os/bsd/vm\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/os/linux/vm\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/os/posix/vm\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/os/solaris/dtrace\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/os/solaris/vm\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/os/windows/vm\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/os_cpu/aix_ppc/vm\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/os_cpu/bsd_x86/vm\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/os_cpu/bsd_zero/vm\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/os_cpu/linux_ppc/vm\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/os_cpu/linux_sparc/vm\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/os_cpu/linux_x86/vm\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/os_cpu/linux_zero/vm\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/os_cpu/solaris_sparc/vm\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/os_cpu/solaris_x86/vm\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/os_cpu/windows_x86/vm\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/tools/hsdis\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/adlc\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/asm\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/c1\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/ci\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/classfile\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/code\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/compiler\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/gc_implementation/g1\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/gc_implementation/parallelScavenge\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/gc_implementation/parNew\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/gc_implementation/shared\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/gc_interface\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/interpreter\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/dcmd\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/instrumentation\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/jni\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/leakprofiler\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/leakprofiler/chains\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/leakprofiler/checkpoint\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/leakprofiler/sampling\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/leakprofiler/utilities\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/metadata\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/periodic\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/periodic/sampling\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/recorder\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/recorder/access\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/recorder/checkpoint\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/recorder/checkpoint/constant\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/recorder/checkpoint/constant/traceid\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/recorder/repository\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/recorder/service\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/recorder/stacktrace\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/recorder/storage\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/recorder/stringpool\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/utilities\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/writers\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jwarmup\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/libadt\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/memory\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/oops\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/opto\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/precompiled\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/prims\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/prims/wbtestmethods\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/runtime\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/services\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/shark\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/trace\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/src/share/vm/utilities\' \'-I\' \'/home/terwer/workspace/dragonwell8/hotspot/test/jfr\' \'-g\' \'-fpch-preprocess\' \'-v\' \'-dD\' \'-E\' \'-D\' \'___CIDR_DEFINITIONS_END\' \'-mtune=generic\' \'-march=x86-64\'\r\n cc1obj -E -quiet -v -I /home/terwer/workspace/dragonwell8/hotspot/agent/src/os/bsd -I /home/terwer/workspace/dragonwell8/hotspot/agent/src/os/linux -I /home/terwer/workspace/dragonwell8/hotspot/agent/src/os/solaris/proc -I /home/terwer/workspace/dragonwell8/hotspot/src/cpu/ppc/vm -I /home/terwer/workspace/dragonwell8/hotspot/src/cpu/sparc/vm -I /home/terwer/workspace/dragonwell8/hotspot/src/cpu/x86/vm -I /home/terwer/workspace/dragonwell8/hotspot/src/cpu/zero/vm -I /home/terwer/workspace/dragonwell8/hotspot/src/os/aix/vm -I /home/terwer/workspace/dragonwell8/hotspot/src/os/bsd/dtrace -I /home/terwer/workspace/dragonwell8/hotspot/src/os/bsd/vm -I /home/terwer/workspace/dragonwell8/hotspot/src/os/linux/vm -I /home/terwer/workspace/dragonwell8/hotspot/src/os/posix/vm -I /home/terwer/workspace/dragonwell8/hotspot/src/os/solaris/dtrace -I /home/terwer/workspace/dragonwell8/hotspot/src/os/solaris/vm -I /home/terwer/workspace/dragonwell8/hotspot/src/os/windows/vm -I /home/terwer/workspace/dragonwell8/hotspot/src/os_cpu/aix_ppc/vm -I /home/terwer/workspace/dragonwell8/hotspot/src/os_cpu/bsd_x86/vm -I /home/terwer/workspace/dragonwell8/hotspot/src/os_cpu/bsd_zero/vm -I /home/terwer/workspace/dragonwell8/hotspot/src/os_cpu/linux_ppc/vm -I /home/terwer/workspace/dragonwell8/hotspot/src/os_cpu/linux_sparc/vm -I /home/terwer/workspace/dragonwell8/hotspot/src/os_cpu/linux_x86/vm -I /home/terwer/workspace/dragonwell8/hotspot/src/os_cpu/linux_zero/vm -I /home/terwer/workspace/dragonwell8/hotspot/src/os_cpu/solaris_sparc/vm -I /home/terwer/workspace/dragonwell8/hotspot/src/os_cpu/solaris_x86/vm -I /home/terwer/workspace/dragonwell8/hotspot/src/os_cpu/windows_x86/vm -I /home/terwer/workspace/dragonwell8/hotspot/src/share/tools/hsdis -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/adlc -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/asm -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/c1 -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/ci -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/classfile -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/code -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/compiler -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/gc_implementation/g1 -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/gc_implementation/parallelScavenge -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/gc_implementation/parNew -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/gc_implementation/shared -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/gc_interface -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/interpreter -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/dcmd -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/instrumentation -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/jni -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/leakprofiler -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/leakprofiler/chains -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/leakprofiler/checkpoint -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/leakprofiler/sampling -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/leakprofiler/utilities -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/metadata -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/periodic -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/periodic/sampling -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/recorder -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/recorder/access -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/recorder/checkpoint -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/recorder/checkpoint/constant -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/recorder/checkpoint/constant/traceid -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/recorder/repository -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/recorder/service -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/recorder/stacktrace -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/recorder/storage -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/recorder/stringpool -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/utilities -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jfr/writers -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/jwarmup -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/libadt -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/memory -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/oops -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/opto -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/precompiled -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/prims -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/prims/wbtestmethods -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/runtime -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/services -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/shark -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/trace -I /home/terwer/workspace/dragonwell8/hotspot/src/share/vm/utilities -I /home/terwer/workspace/dragonwell8/hotspot/test/jfr -D ___CIDR_DEFINITIONS_END /tmp/compiler-file8800302653913998230 -mtune=generic -march=x86-64 -fpch-preprocess -g -fworking-directory -dD\r\n cc: error trying to exec \'cc1obj\': execvp: No such file or directory\r\n \r\n \r\n\r\n[Failed to reload]\r\n```\r\n\r\n解决\r\n\r\nhttp://nullwy.me/2018/02/build-debug-openjdk/\r\n\r\n# Eclipse调试\r\n\r\nhttps://blog.csdn.net/tjiyu/article/details/53725247\r\n# 参考\r\nhttps://www.jianshu.com/p/ee7e9176632c', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7851, '', 'JAVA虚拟机学习笔记(二)构建dragonwell8的docker镜像', '2019-03-30 19:47:21', '2019-12-03 01:51:27', '# 编写Dockerfile\r\n\r\n在编写Dockerfile之前要做三个重要的选择,如下: \r\n\r\n## 选择linux\r\n\r\n推荐centos7\r\n\r\n## 获取dragonwell8源码\r\n\r\n这次要编译的是dragonwell8,源码的下载地址在这里 [https://github.com/terwer/dragonwell8 ](https://github.com/terwer/dragonwell8 ) ,这个版本经过了我的部分修正,修复了编译环境问题\r\n\r\n## Bootstrap JDK\r\n\r\n即编译时要用到的JDK,下载了 `dragonwell8` 的源码后,解压开可以看到 `README-builds.html` 这个文件,里面有对 `Bootstrap JDK` 的描述。\r\n\r\n\r\n# Dockefile\r\n```\r\n#依赖的镜像\r\nFROM ubuntu:14.04\r\n#镜像创建者的信息\r\nMAINTAINER terwer \"cbgtyw@gmail.com\"\r\n# 设置编码\r\nENV LANG C.UTF-8\r\n# 设置时区\r\n# ENV TZ Asia/Shanghai\r\nENV TZ CST-8\r\n```\r\n\r\n# docker-compose.yml\r\n```\r\nversion: \'3\'\r\nservices:\r\n docker-draggonwell8:\r\n image: terwer/draggonwell8\r\n container_name: docker-draggonwell8\r\n build:\r\n context: ./\r\n dockerfile: ./Dockerfile\r\n ports:\r\n - 22:22\r\n volumes:\r\n - ./build:/home/docker-draggonwell8/build\r\n```\r\n\r\n# Github\r\n\r\n[https://github.com/terwer/docker-dragonwell8](https://github.com/terwer/docker-dragonwell8)', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7852, '', 'CentOS7使用SS和proxychains访问代理服务', '2019-03-31 02:16:27', '2019-09-10 13:16:17', '> 2019/04/07 验证通过 \r\n# Shadowsocks客户端安装\r\n\r\n## 安装\r\n```\r\nwget -c https://bootstrap.pypa.io/get-pip.py\r\npip install shadowsocks\r\n```\r\n\r\n## 修改配置\r\n\r\n```\r\nvim ~/sslocal.json\r\n```\r\n\r\n修改为\r\n\r\n```json\r\n{\r\n\"server\" : \"xx.xx.xx.xx\",\r\n\"server_port\" : 0000,\r\n\"password\" : \"xxxxxx\",\r\n\"method\" : \"aes-256-cfb\",\r\n\"remarks\" : \"vpn-name\"\r\n}\r\n```\r\n\r\n## 启动\r\n\r\n```\r\nsudo sslocal -c ~/sslocal.json -d start\r\n```\r\n\r\n## 停止\r\n\r\n```\r\nsudo sslocal -c ~/sslocal.json -d stop\r\n```\r\n\r\n# 安装proxychains-ng\r\n\r\n## 安装\r\n```\r\ncd /usr/local/src\r\ngit clone https://github.com/rofl0r/proxychains-ng.git\r\ncd proxychains-ng\r\n./configure --prefix=/usr --sysconfdir=/etc\r\nmake && make install\r\nmake install-config\r\ncd .. && rm -rf proxychains-ng\r\n```\r\n\r\n## 修改配置端口为ss代理端口\r\n\r\n```\r\nvim /etc/proxychains.conf\r\n```\r\n\r\n在最下面加上一行\r\n\r\n```\r\nsocks5 127.0.0.1 1080\r\n```\r\n\r\n# 测试\r\n\r\n```\r\nproxychains4 curl ip.cn\r\n```\r\n\r\n# 安装Google Chrome\r\n\r\n```\r\nwget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb\r\n```\r\n\r\n启动\r\n\r\n```\r\nsudo proxychains4 google-chrome-stable --no-sandbox\r\n```\r\n\r\n# 错误解决\r\n\r\n`undefined symbol: EVP_CIPHER_CTX_cleanup`\r\n\r\nhttps://blog.csdn.net/alex_bean/article/details/86500662\r\n', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7854, '', '在CentOS 7.6上安装VNC Server', '2019-03-31 04:45:00', '2019-12-02 02:45:30', '# 停止并禁用防火墙\r\n```\r\nsystemctl stop firewalld.service\r\nsystemctl disable firewalld.service\r\n```\r\n\r\n# 安装vnxserver\r\n\r\n```\r\nyum install tigervnc tigervnc-server -y\r\n```\r\n\r\n# 修改配置文件(解决连接空白问题)\r\n修改 `~/.vnc/xstartup`,\r\n\r\n完整配置文件如下:\r\n\r\n```\r\n#!/bin/sh\r\n \r\n# Uncomment the following two lines for normal desktop:\r\n# unset SESSION_MANAGER\r\n# exec /etc/X11/xinit/xinitrc\r\n \r\n[ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup\r\n[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources\r\nxsetroot -solid grey \r\nvncconfig -iconic &\r\n# x-terminal-emulator -geometry 80x24+10+10 -ls -title \"$VNCDESKTOP Desktop\" &\r\n \r\nmate-session &\r\n```\r\n\r\n# 启动vncserver(服务器端)\r\n\r\n```\r\nvncserver :n \r\n```\r\n\r\n这里的n是 `sessionnumber` ,不指定默认为1,也可以是2、3等等。第一次会提示输入密码,以后可以使用 `vncpasswd` 命令修改密码。\r\n\r\n\r\n```\r\nsudo systemctl start vncserver@:1.service\r\n\r\n➜ ~ sudo systemctl daemon-reload\r\n➜ ~ sudo systemctl restart vncserver@:1.service\r\n➜ ~ sudo systemctl status vncserver@:1.service -l\r\n```\r\n\r\n# 在Windows上安装 `vncviewer`\r\n\r\n[https://terwer.oss-cn-qingdao.aliyuncs.com/soft/vncviewer64-1.9.0.exe](https://terwer.oss-cn-qingdao.aliyuncs.com/soft/vncviewer64-1.9.0.exe)\r\n\r\nVNC的默认端口是5900,而远程桌面连接端口则是5900+n(n是vncserver命令指定的)。如果使用“vncserver :1”命令启动VNC Server,那么下面的端口应该是5901。\r\n\r\n# 参考\r\n\r\n```\r\nhttps://www.htcp.net/880.html\r\n```\r\n', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7855, '', 'Chrome launch with socks5 proxy', '2019-03-31 08:44:53', '2019-09-07 10:01:26', '```\r\ngoogle-chrome --proxy-server=\"socks5://127.0.0.1:1080\" --no-sandbox --user-data-dir &\r\n```', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7856, '', 'Docker安装Oracle 12c', '2019-04-01 06:43:59', '2019-09-09 12:16:58', '# 拉取docker镜像\r\n需要先登录\r\n\r\n```\r\ndocker login\r\n```\r\n\r\n拉取镜像\r\n\r\n```\r\ndocker pull store/oracle/database-enterprise:12.2.0.1\r\n```\r\n# `Dockerfile`\r\n```\r\n#依赖的镜像\r\nFROM store/oracle/database-enterprise:12.2.0.1\r\n#镜像创建者的信息\r\nMAINTAINER terwer \"csyouwei@gmail.com\"\r\n# 设置编码\r\nENV LANG C.UTF-8\r\n# 设置时区\r\n# ENV TZ Asia/Shanghai\r\nENV TZ CST-8\r\n```\r\n\r\n# `docker-compose.yml`\r\n\r\n```\r\n# 构建docker-compose项目\r\n# docker-compose --log-level INFO build\r\n# docker-compose --log-level INFO build jvue-front\r\n\r\n# 重启并清理以及重建容器\r\n# docker-compose --log-level INFO up --force-recreate --remove-orphans\r\n# docker-compose --log-level INFO up --force-recreate jvue-front\r\n\r\n# 重启并重建镜像\r\n# docker-compose --log-level INFO up --build --force-recreate --remove-orphans\r\n# docker-compose --log-level INFO up --build --force-recreate jvue-oracle\r\n\r\n# 启动守护线程\r\n# docker-compose --log-level INFO up -d\r\n\r\n# 重启并重建镜像启动守护线程\r\n# docker-compose --log-level INFO up -d --build --force-recreate jvue-oracle\r\n\r\nversion: \'3\'\r\nservices:\r\n jvue-oracle:\r\n privileged: true\r\n image: jvue/oracle:12.2.0.1\r\n container_name: jvue-oracle\r\n build:\r\n context: ./\r\n dockerfile: ./jvue-oracle/Dockerfile\r\n ports:\r\n - \"1521:1521\"\r\n volumes:\r\n - ./data/oracle/setup/log:/home/oracle/setup/log\r\n - ./data/oracle:/u01/app/oracle\r\n restart: always\r\n```\r\n\r\n# 启动\r\n\r\n```\r\ndocker-compose up jvue-oracle\r\n```\r\n\r\nlog1\r\n\r\n```\r\n➜ jvue git:(master) ✗ docker-compose up jvue-oracle\r\nBuilding jvue-oracle\r\nStep 1/4 : FROM store/oracle/database-enterprise:12.2.0.1\r\n ---> 12a359cd0528\r\nStep 2/4 : MAINTAINER terwer \"csyouwei@gmail.com\"\r\n ---> Running in 964d828f7294\r\nRemoving intermediate container 964d828f7294\r\n ---> 45f68bfd4143\r\nStep 3/4 : ENV LANG C.UTF-8\r\n ---> Running in eb8909b48cda\r\nRemoving intermediate container eb8909b48cda\r\n ---> c1b3d5a94baf\r\nStep 4/4 : ENV TZ CST-8\r\n ---> Running in ce7cdf3e22d8\r\nRemoving intermediate container ce7cdf3e22d8\r\n ---> eb82178d3c2c\r\nSuccessfully built eb82178d3c2c\r\nSuccessfully tagged jvue/oracle:12.2.0.1\r\nWARNING: Image for service jvue-oracle was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.\r\nCreating jvue-oracle ... done\r\nAttaching to jvue-oracle\r\njvue-oracle | Setup Oracle Database\r\njvue-oracle | Oracle Database 12.2.0.1 Setup\r\njvue-oracle | Sun Mar 31 23:13:10 CST 2019\r\njvue-oracle |\r\njvue-oracle | Check parameters ......\r\njvue-oracle | log file is : /home/oracle/setup/log/paramChk.log\r\njvue-oracle | paramChk.sh is done at 0 sec\r\njvue-oracle |\r\njvue-oracle | untar DB bits ......\r\njvue-oracle | log file is : /home/oracle/setup/log/untarDB.log\r\njvue-oracle | untarDB.sh is done at 75 sec\r\njvue-oracle |\r\njvue-oracle | config DB ......\r\njvue-oracle | log file is : /home/oracle/setup/log/configDB.log\r\n```\r\n\r\nlog2\r\n\r\n```\r\nConnected to:\r\njvue-oracle | Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production\r\njvue-oracle |\r\njvue-oracle | SQL>\r\njvue-oracle | System altered.\r\njvue-oracle |\r\njvue-oracle | SQL> Disconnected from Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production\r\njvue-oracle |\r\njvue-oracle | LSNRCTL for Linux: Version 12.2.0.1.0 - Production on 31-MAR-2019 22:40:03\r\njvue-oracle |\r\njvue-oracle | Copyright (c) 1991, 2016, Oracle. All rights reserved.\r\njvue-oracle |\r\njvue-oracle | Starting /u01/app/oracle/product/12.2.0/dbhome_1/bin/tnslsnr: please wait...\r\njvue-oracle |\r\njvue-oracle | TNSLSNR for Linux: Version 12.2.0.1.0 - Production\r\njvue-oracle | System parameter file is /u01/app/oracle/product/12.2.0/dbhome_1/admin/ORCLCDB/listener.ora\r\njvue-oracle | Log messages written to /u01/app/oracle/diag/tnslsnr/389b169aa1f9/listener/alert/log.xml\r\njvue-oracle | Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=0.0.0.0)(PORT=1521)))\r\njvue-oracle | Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))\r\njvue-oracle |\r\njvue-oracle | Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=0.0.0.0)(PORT=1521)))\r\njvue-oracle | STATUS of the LISTENER\r\njvue-oracle | ------------------------\r\njvue-oracle | Alias LISTENER\r\njvue-oracle | Version TNSLSNR for Linux: Version 12.2.0.1.0 - Production\r\njvue-oracle | Start Date 31-MAR-2019 22:40:04\r\njvue-oracle | Uptime 0 days 0 hr. 0 min. 0 sec\r\njvue-oracle | Trace Level off\r\njvue-oracle | Security ON: Local OS Authentication\r\njvue-oracle | SNMP OFF\r\njvue-oracle | Listener Parameter File /u01/app/oracle/product/12.2.0/dbhome_1/admin/ORCLCDB/listener.ora\r\njvue-oracle | Listener Log File /u01/app/oracle/diag/tnslsnr/389b169aa1f9/listener/alert/log.xml\r\njvue-oracle | Listening Endpoints Summary...\r\njvue-oracle | (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=0.0.0.0)(PORT=1521)))\r\njvue-oracle | (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))\r\njvue-oracle | The listener supports no services\r\njvue-oracle | The command completed successfully\r\njvue-oracle |\r\njvue-oracle | DONE!\r\njvue-oracle | Remove password info\r\njvue-oracle | Docker DB configuration is complete !\r\njvue-oracle | configDB.sh is done at 109 sec\r\njvue-oracle |\r\njvue-oracle | Done ! The database is ready for use .\r\njvue-oracle | # ===========================================================================\r\njvue-oracle | # == Add below entries to your tnsnames.ora to access this database server ==\r\njvue-oracle | # ====================== from external host =================================\r\njvue-oracle | ORCLCDB=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=)(PORT=))\r\njvue-oracle | (CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=ORCLCDB.localdomain)))\r\njvue-oracle | ORCLPDB1=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=)(PORT=))\r\njvue-oracle | (CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=ORCLPDB1.localdomain)))\r\njvue-oracle | #\r\njvue-oracle | #ip-address : IP address of the host where the container is running.\r\njvue-oracle | #port : Host Port that is mapped to the port 1521 of the container.\r\njvue-oracle | #\r\njvue-oracle | # The mapped port can be obtained from running \"docker port \"\r\njvue-oracle | # ===========================================================================\r\njvue-oracle | Thread 1 advanced to log sequence 5 (LGWR switch)\r\njvue-oracle | Current log# 2 seq# 5 mem# 0: /u04/app/oracle/redo/redo002.log\r\njvue-oracle | 2019-03-31T22:40:03.646828+08:00\r\njvue-oracle | ORCLPDB1(3):Opening pdb with no Resource Manager plan active\r\njvue-oracle | Pluggable database ORCLPDB1 opened read write\r\njvue-oracle | Completed: alter pluggable database ORCLPDB1 open\r\njvue-oracle | alter pluggable database all save state\r\njvue-oracle | Completed: alter pluggable database all save state\r\njvue-oracle | 2019-03-31T22:40:03.930545+08:00\r\njvue-oracle | ALTER SYSTEM SET encrypt_new_tablespaces=\'DDL\' SCOPE=BOTH;\r\njvue-oracle | 2019-03-31T22:40:40.221212+08:00\r\njvue-oracle | TABLE SYS.WRP$_REPORTS: ADDED INTERVAL PARTITION SYS_P287 (3377) VALUES LESS THAN (TO_DATE(\' 2019-04-01 01:00:00\', \'SYYYY-MM-DD HH24:MI:SS\', \'NLS_CALENDAR=GREGORIAN\'))\r\njvue-oracle | TABLE SYS.WRP$_REPORTS_DETAILS: ADDED INTERVAL PARTITION SYS_P288 (3377) VALUES LESS THAN (TO_DATE(\' 2019-04-01 01:00:00\', \'SYYYY-MM-DD HH24:MI:SS\', \'NLS_CALENDAR=GREGORIAN\'))\r\njvue-oracle | TABLE SYS.WRP$_REPORTS_TIME_BANDS: ADDED INTERVAL PARTITION SYS_P291 (3376) VALUES LESS THAN (TO_DATE(\' 2019-03-31 01:00:00\', \'SYYYY-MM-DD HH24:MI:SS\', \'NLS_CALENDAR=GREGORIAN\'))\r\n```\r\n\r\n# 默认值\r\n\r\n```\r\n# DB_SID\r\n# This parameter changes the ORACLE_SID of the database. The default value is set to ORCLCDB.\r\n# To connect from outside the container using SQL*Plus,\r\n# $ sqlplus sys/Oradoc_db1@ORCLCDB as sysdba\r\n# Changing default password for SYS user\r\n# alter user sys identified by ;\r\n# The database alert log can be viewed with\r\n# $ docker logs \r\n```\r\n\r\n# 安装示例数据库\r\n\r\n```\r\ncurl https://codeload.github.com/oracle/db-sample-schemas/zip/v12.2.0.1 -o db-sample-schemas.zip\r\n```', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7857, '', 'Docker空间清理', '2019-04-01 08:18:59', '2019-06-21 03:06:19', '# 查看占用情况\r\n\r\n```\r\ndocker system df -v\r\n```\r\n\r\n# 清理\r\n\r\n## 无用容器清理\r\n\r\n```\r\ndocker system prune -a\r\n```\r\n\r\n## 卷清理\r\n\r\n如果通过 `docker system df` 分析,是卷占用了过高空间。则可以根据业务情况,评估相关卷的使用情况。对于未被任何容器调用的卷(-v 结果信息中,\"LINKS\" 显示为 0),可以使用如下指令手工清理:\r\n\r\n```\r\n# 删除所有未被任何容器关联引用的卷:\r\ndocker volume rm $(docker volume ls -qf dangling=true)\r\n\r\n# 也可以直接使用如下指令,删除所有未被任何容器关联引用的卷(但建议使用上面的方式)\r\n# 【说明】轮询到还在使用的卷时,会有类似\"volume is in use\"的告警信息,所以相关卷不会被删除,忽略即可。\r\ndocker volume rm $(docker volume ls -q)\r\n```\r\n\r\n## 容器清理\r\n\r\n如果通过 `docker system df` 分析,是某个容器占用了过高空间。则可以根据业务情况,评估相关容器的业务归属并进行处理。对于已停止或其它异常状态的容器,可以结合 `-f` 或 `--filter` 筛选器,使用类似如下指令来手工清理:\r\n\r\n```\r\n# 删除所有已退出的容器\r\ndocker rm -v $(docker ps -aq -f status=exited)\r\n# 删除所有状态为 dead 的容器\r\ndocker rm -v $(docker ps -aq -f status=dead)\r\n```', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7858, '', 'CentOS7查看性能指标', '2019-04-01 19:13:09', '2019-07-15 05:07:09', '# 查看内存\r\n\r\n```\r\nfree -mh\r\n```\r\n\r\nlog\r\n\r\n```\r\n➜ free -mh\r\n total used free shared buff/cache available\r\nMem: 3.7G 1.7G 143M 1.3G 1.9G 522M\r\nSwap: 0B 0B 0B\r\n```\r\n\r\n# 查看磁盘剩余空间\r\n\r\n```\r\ndf -lh\r\n```\r\n\r\nlog\r\n\r\n```\r\n➜ df -lh\r\nFilesystem Size Used Avail Use% Mounted on\r\n/dev/vda1 40G 20G 19G 52% /\r\n```', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7859, '', 'CentOS设置swap分区', '2019-04-01 19:16:54', '2019-06-10 10:29:25', '# 检查 Swap 空间\r\n\r\n在设置 Swap 文件之前,有必要先检查一下系统里有没有既存的 Swap 文件。运行以下命令:\r\n\r\n```\r\nswapon -s\r\n```\r\n\r\n如果返回的信息概要是空的,则表示 Swap 文件不存在。\r\n\r\n# 查看剩余空间\r\n\r\n检查文件系统在设置 Swap 文件之前,同样有必要检查一下文件系统,看看是否有足够的硬盘空间来设置 Swap 。运行以下命令:\r\n\r\n```\r\ndf -hal\r\n```\r\n\r\n# 创建swap文件\r\n\r\n创建并允许 Swap 文件下面使用 dd 命令来创建 Swap 文件。检查返回的信息,还剩余足够的硬盘空间即可。\r\n\r\n```\r\ndd if=/dev/zero of=/swapfile bs=1024 count=3072k\r\n```\r\n\r\nhttps://itsfoss.com/swap-size/\r\n\r\nhttps://www.tecmint.com/create-a-linux-swap-file/\r\n\r\n\r\n# 格式化\r\n\r\n格式化并激活 Swap 文件上面已经创建好 Swap 文件,还需要格式化后才能使用。运行命令:\r\n\r\n```\r\nmkswap /swapfile\r\n```\r\n\r\n激活 Swap ,运行命令:\r\n\r\n```\r\nswapon /swapfile\r\n```\r\n\r\n以上步骤做完,运行命令:\r\n\r\n```\r\nfree -mh\r\n```\r\n\r\n你会发现返回的信息概要:\r\n\r\n```\r\n➜ free -mh\r\n total used free shared buff/cache available\r\nMem: 3.7G 1.7G 133M 1.3G 1.9G 538M\r\nSwap: 3.0G 0B 3.0G\r\n```\r\n\r\n# 设置自动重启\r\n如果要机器重启的时候自动挂载 `Swap` ,那么还需要修改 `fstab` 配置。用 `vim` 打开 `/etc/fstab` 文件,在其最后添加如下一行:\r\n\r\n```\r\n/swapfile swap swap defaults 0 0\r\n```\r\n最后,赋予 Swap 文件适当的权限:\r\n\r\n```\r\nchown root:root /swapfile \r\nchmod 0600 /swapfile\r\n```\r\n\r\n', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7860, '', 'Linux查看物理CPU个数、核数、逻辑CPU个数', '2019-04-01 19:25:32', '2019-11-30 12:41:34', '```\r\n# 总核数 = 物理CPU个数 X 每颗物理CPU的核数 \r\n# 总逻辑CPU数 = 物理CPU个数 X 每颗物理CPU的核数 X 超线程数\r\n\r\n# 查看物理CPU个数\r\ncat /proc/cpuinfo| grep \"physical id\"| sort| uniq| wc -l\r\n\r\n# 查看每个物理CPU中core的个数(即核数)\r\ncat /proc/cpuinfo| grep \"cpu cores\"| uniq\r\n\r\n# 查看逻辑CPU的个数\r\ncat /proc/cpuinfo| grep \"processor\"| wc -l\r\n```\r\n\r\n 查看CPU信息(型号)\r\n \r\n```\r\ncat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c\r\n```', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7861, '', 'How to enable Oracle Enterprise Manager Express 12c', '2019-04-01 20:01:01', '2019-05-05 17:12:50', 'https://emarcel.com/oem-express-12c/', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7862, '', 'ET接口文档', '2019-04-01 23:55:12', '2019-11-27 22:38:16', '# 课程信息\r\n\r\n 入参:\r\n \r\n 课程id / tokenString / 当前页码\r\n \r\n 出参:\r\n \r\n 1. 教材\r\n \r\n 2. 页码\r\n \r\n 3. 老师\r\n \r\n 4. 日期\r\n\r\n# 知识点列表(已经有)\r\n 入参:\r\n \r\n 课程id / tokenString\r\n \r\n 出参:\r\n \r\n 1. 教材\r\n \r\n 2. 页码\r\n \r\n 3. 老师\r\n \r\n 4. 日期\r\n\r\n# 题目列表(解析列表)\r\n 入参:\r\n \r\n isUnderstand 对错,-1 全部/1 正确/0 错\r\n\r\n lessonId 课程ID\r\n\r\n pageNumber 页码,默认1\r\n\r\n pageSize 每页展示的数目,默认10\r\n\r\n qknowledgeId 知识点ID\r\n\r\n tokenString 用户token\r\n\r\n version 版本号\r\n \r\n 出参:\r\n \r\n 参数和解析保持一致,\r\n\r\n add :\r\n isUnderstand 该题目对应的考点是否掌握 0 / 1\r\n\r\n# 更新掌握状态\r\n 课程id / 知识id / 考点id / 题目id / tokenString / version(+1)/ state(改变后的)\r\n\r\n 做题记录表添加一个:考点对应的题目是否掌握字段', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (7863, '', 'JAVA虚拟机学习笔记(四)类加载器深入解析与阶段分解', '2019-04-03 08:47:52', '2019-12-03 01:53:07', '# 类加载\r\n* 在Java代码中,类型的 `加载` 、`链接` 与 `初始化` 过程都是在程序运行期间决定的。\r\n* 提供了更强大的灵活性,增加了更多的可能性。\r\n# 类加载深入剖析\r\n在如下几种情况,Java虚拟机将会结束生命周期\r\n\r\n* 执行了 `System.exit()` 方法\r\n* 程序正常执行结束\r\n* 程序在执行过程中遇到了异常而异常终止\r\n* 由于操作系统错误导致Java虚拟机进程终止\r\n# 类的加载、连接与初始化\r\n* 加载:查找并加载类的二进制数据\r\n* 链接\r\n> - 验证:确保被加载类的正确性\r\n\r\n> - 准备:为类的静态变量分配内存,并将其初始化为默认值\r\n\r\n> - 解析:将类中的符号引用转换为直接引用\r\n* 初始化:为类的静态变量赋予正确的初始化值', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7864, '', 'Linux Vim修改字体', '2019-04-08 06:10:42', '2019-05-03 14:29:33', '修改文件 `sudo vim /etc/vim/vimrc`\r\n\r\n或者 `sudo vim /etc/vim/vimrc.local `\r\n\r\n\r\n\r\n# Gvim\r\n\r\n`sudo apt install vim-gtk`\r\n\r\n添加下面的内容\r\n\r\n```\r\ncolor torte\r\nset number\r\nset guifont=Dejavu\\ Sans\\ Mono\\ Book\\ 24\r\n```', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7865, '', '解决git clone大项目或者网速差的时候出现的 RPC failed; curl 18 transfer closed with outstanding read data remaining', '2019-04-09 02:51:47', '2019-12-03 01:50:11', '# 操作\r\n\r\n```\r\ngit config http.postBuffer 524288000\r\n\r\n\r\ngit clone http://github.com/large-repository --depth 1\r\ncd large-repository\r\ngit fetch --unshallow\r\n```\r\n\r\n# 日志\r\n\r\n```\r\nC:\\Users\\Terwer\\VSProjects> git clone https://github.com/AdoptOpenJDK/openjdk-jdk11u.git --depth 1\r\nCloning into \'openjdk-jdk11u\'...\r\nremote: Enumerating objects: 81021, done.\r\nremote: Counting objects: 100% (81021/81021), done.\r\nremote: Compressing objects: 100% (40252/40252), done.\r\nReceiving objects: 76% (61576/81021), 107.17 MiB | 1.12 MiB/s\r\nResolving deltas: 100% (44518/44518), done.\r\nChecking out files: 100% (66258/66258), done.\r\n\r\nC:\\Users\\Terwer\\VSProjects>\r\n```', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7866, '', 'Ubuntu 18.04.2 LTS修改默认gcc版本', '2019-04-09 20:35:02', '2019-08-06 07:52:18', '# 安装多版本gcc、g++\r\n```\r\nsudo apt-get install gcc-4.8 gcc-7 g++-4.8 g++-7\r\n```\r\n\r\n# Install Alternatives\r\n```\r\nsudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 10\r\nsudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 20\r\n\r\nsudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 10\r\nsudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-7 20\r\n\r\nsudo update-alternatives --install /usr/bin/cc cc /usr/bin/gcc 30\r\nsudo update-alternatives --set cc /usr/bin/gcc\r\n\r\nsudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++ 30\r\nsudo update-alternatives --set c++ /usr/bin/g++\r\n```\r\n\r\n# Configure Alternatives\r\n\r\n```\r\nsudo update-alternatives --config gcc\r\nsudo update-alternatives --config g++\r\n```\r\n\r\n\r\n# 日志\r\n\r\n```\r\nterwer@WORK:~$ sudo update-alternatives --config gcc\r\nThere are 2 choices for the alternative gcc (providing /usr/bin/gcc).\r\n\r\n Selection Path Priority Status\r\n------------------------------------------------------------\r\n* 0 /usr/bin/gcc-7 20 auto mode\r\n 1 /usr/bin/gcc-4.8 10 manual mode\r\n 2 /usr/bin/gcc-7 20 manual mode\r\n\r\nPress to keep the current choice[*], or type selection number: 1\r\nupdate-alternatives: using /usr/bin/gcc-4.8 to provide /usr/bin/gcc (gcc) in manual mode\r\nterwer@WORK:~$ sudo update-alternatives --config g++\r\nThere are 2 choices for the alternative g++ (providing /usr/bin/g++).\r\n\r\n Selection Path Priority Status\r\n------------------------------------------------------------\r\n* 0 /usr/bin/g++-7 20 auto mode\r\n 1 /usr/bin/g++-4.8 10 manual mode\r\n 2 /usr/bin/g++-7 20 manual mode\r\n\r\nPress to keep the current choice[*], or type selection number: 1\r\nupdate-alternatives: using /usr/bin/g++-4.8 to provide /usr/bin/g++ (g++) in manual mode\r\nterwer@WORK:~$ gcc -v\r\nUsing built-in specs.\r\nCOLLECT_GCC=gcc\r\nCOLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.8/lto-wrapper\r\nTarget: x86_64-linux-gnu\r\nConfigured with: ../src/configure -v --with-pkgversion=\'Ubuntu 4.8.5-4ubuntu8\' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs --enable-languages=c,c++,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.8 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-libmudflap --enable-plugin --with-system-zlib --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu\r\nThread model: posix\r\ngcc version 4.8.5 (Ubuntu 4.8.5-4ubuntu8)\r\n```\r\n\r\nhttps://askubuntu.com/questions/26498/how-to-choose-the-default-gcc-and-g-version', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7867, '', 'Github git clone设置代理及提高下载速度', '2019-04-09 22:59:38', '2019-06-13 19:48:56', '```\r\ngit clone -c http.proxy=socks5://127.0.0.1:1080 http://github.com/me/test1.git\r\n```\r\n或者\r\n\r\n```\r\ngit config --global http.proxy \"socks5://127.0.0.1:1080\"\r\n```\r\n\r\n取消\r\n\r\n```\r\ngit config --global --unset http.proxy\r\ngit config --global --unset https.proxy\r\n```\r\n\r\n# 提速\r\n\r\n```\r\ngit config --global http.postBuffer 524288000\r\n```\r\n\r\nhttps://blog.51cto.com/11887934/2051323', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7868, '', 'Ubuntu12.0.4 LTS编译OpenJDK11', '2019-04-10 00:49:12', '2019-08-31 23:31:47', '# src\r\n```\r\ngit clone https://github.com/terwer/openjdk-jdk11u.git --depth 1\r\n```\r\n\r\n# 配置\r\n\r\n```\r\n./configure --with-boot-jdk=/opt/java/jdk-11.0.2 --with-freetype-include=/usr/include/freetype2 --with-freetype-lib=/usr/lib/x86_64-linux-gnu --with-debug-level=slowdebug --with-native-debug-symbols=internal --disable-warnings-as-errors --with-jvm-variants=server --with-target-bits=64 --enable-ccache --with-num-cores=4 --with-memory-size=5000\r\n```\r\n# log\r\n\r\n```\r\n====================================================\r\nA new configuration has been successfully created in\r\n/mnt/c/Users/Terwer/WSLProjects/openjdk-jdk11u/build/linux-x86_64-normal-server-slowdebug\r\nusing configure arguments \'--with-boot-jdk=/opt/java/jdk-11.0.2 --with-freetype-include=/usr/include/freetype2 --with-freetype-lib=/usr/lib/x86_64-linux-gnu --with-debug-level=slowdebug --with-native-debug-symbols=internal --with-jvm-variants=server --with-target-bits=64 --enable-ccache --with-num-cores=4 --with-memory-size=3000\'.\r\n\r\nConfiguration summary:\r\n* Debug level: slowdebug\r\n* HS debug level: debug\r\n* JVM variants: server\r\n* JVM features: server: \'aot cds cmsgc compiler1 compiler2 epsilongc g1gc graal jfr jni-check jvmci jvmti management nmt parallelgc serialgc services vm-structs zgc\'\r\n* OpenJDK target: OS: linux, CPU architecture: x86, address length: 64\r\n* Version string: 11.0.3-internal+0-adhoc.terwer.openjdk-jdk11u (11.0.3-internal)\r\n\r\nTools summary:\r\n* Boot JDK: java version \"11.0.2\" 2019-01-15 LTS Java(TM) SE Runtime Environment 18.9 (build 11.0.2+9-LTS) Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.2+9-LTS, mixed mode) (at /opt/java/jdk-11.0.2)\r\n* Toolchain: gcc (GNU Compiler Collection)\r\n* C Compiler: Version 4.8.5 (at /usr/bin/gcc)\r\n* C++ Compiler: Version 4.8.5 (at /usr/bin/g++)\r\n\r\nBuild performance summary:\r\n* Cores to use: 2\r\n* Memory limit: 3000 MB\r\n* ccache status: Active (3.4.1)\r\n```\r\n\r\n# Build\r\n\r\n```\r\nsudo make images\r\n```', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7869, '', 'WSL Ubuntu18.04.2安装mate Desktop并远程VNC', '2019-04-10 08:24:31', '2019-11-27 22:35:22', '> 2019/04/09 验证通过 \r\n# 安装桌面环境\r\n```\r\nsudo apt-get install mate-desktop-environment -y\r\n```\r\n\r\n# 安装VNCServer\r\n```\r\nsudo apt-get install vnc4server\r\n```\r\n\r\n# 配置启动\r\n```\r\nsed -i \'s$x-window-manager$mate-session$\' ~/.vnc/xstartup\r\n```\r\n\r\nor\r\n\r\n ~/.vnc/xstartup 末尾\r\n\r\n```\r\nmate-session &\r\n```\r\n\r\n打开 realvnc 并在地址栏中输入:`127.0.0.1:1` ,点连接并输入连接密码,如果不出意外,你就可以看到安装有 mate 桌面的 Ubuntu 界面了!\r\n# 启动VNC\r\n\r\n```\r\nvncserver\r\n```\r\n\r\n# 关闭VNC\r\n```\r\nvncserver -kill :1\r\n```\r\n\r\n\r\n扩展\r\n\r\ndeepin dde on ubuntu(not working)\r\n\r\nhttps://launchpad.net/~leaeasy/+archive/ubuntu/dde\r\n\r\ngnome(not working)\r\n\r\nhttps://www.cyberciti.biz/faq/install-and-configure-tigervnc-server-on-ubuntu-18-04/\r\n\r\nxface (testing)\r\n\r\nhttps://www.howtoing.com/how-to-install-and-configure-vnc-on-ubuntu-18-04', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7870, '', 'Fedora 29 使用zsh', '2019-04-10 19:31:18', '2019-12-03 11:15:23', '```\r\nsudo dnf install zsh -y\r\nsudo dnf install util-linux-user -y\r\nhttps://github.com/robbyrussell/oh-my-zsh\r\nhttps://github.com/zsh-users/zsh-syntax-highlighting\r\nsudo chsh -s /bin/zsh terwer\r\n```\r\n\r\n\r\nhttps://www.xvideos.com/video33259171/_1080_avonemy.com', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7871, '', 'Feora29安装图形界面', '2019-04-10 19:41:33', '2019-12-01 04:28:41', '> 2019/04/13 验证通过 \r\n> \r\n# 预览\r\n\r\n![](https://terwer.oss-cn-qingdao.aliyuncs.com/bugucms/20190410154421.png)\r\n\r\nhttps://stackoverflow.com/questions/42371319/fedora-25-tigervnc-displays-black-screen\r\n\r\nhttps://docs.fedoraproject.org/en-US/quick-docs/switching-desktop-environments/\r\n\r\n# 下载\r\n[Fedora-Workstation 29](https://download.fedoraproject.org/pub/fedora/linux/releases/29/Workstation/x86_64/iso/Fedora-Workstation-Live-x86_64-29-1.2.iso)\r\n# 添加网易源\r\n```\r\nsudo rm -rf /etc/yum.repos.d/fedora* \r\nsudo curl -o /etc/yum.repos.d/fedora.repo http://mirrors.163.com/.help/fedora-163.repo\r\nsudo curl -o /etc/yum.repos.d/fedora-updates.repo http://mirrors.163.com/.help/fedora-updates-163.repo\r\nsudo dnf clean all\r\nsudo dnf makecache\r\n```\r\n# 安装必备组件\r\n```\r\nsudo dnf install passwd -y \r\nsudo dnf install wget git vim -y \r\n# yum install zsh -y\r\n# sh -c \"$(wget https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh -O -)\"\r\n# git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting\r\n# vim ~/.zshrc\r\n# plugins=(git zsh-syntax-highlighting)\r\n\r\nsudo dnf install util-linux-user -y\r\nsudo chsh -s /bin/zsh terwer\r\nsudo chsh -s /bin/zsh root\r\n```\r\n\r\n# 安装xfce桌面环境\r\n\r\n```\r\nsudo dnf groupinstall -y \"Xfce Desktop\"\r\nsudo dnf install @developer-workstation-environment -y \r\n```\r\n# VNC使用\r\n\r\n## 安装VNC\r\n\r\n```\r\nsudo dnf -y install tigervnc-server -y\r\n```\r\n\r\n## 启动VNCServer\r\n\r\n```\r\nvncserver\r\n```\r\n\r\n## 停止VNCServer\r\n\r\n```\r\nvncserver -kill :1\r\n```\r\n\r\n修改 `~/.vnc/xstartup`\r\n\r\n```\r\n#!/bin/sh\r\n\r\nxrdb $HOME/.Xresources\r\nstartxfce4 &\r\n```\r\n\r\nhttp://www.terwergreen.com/post-dark/7854.html\r\n\r\n\r\n# 安装输入法\r\n\r\n```bash\r\nsudo dnf -y install fcitx fcitx-qt4 fcitx-configtool sunpinyin sunpinyin-data fcitx-sunpinyin im-chooser \r\n```', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7872, '', 'Fedora29 配置网易阿里云yum源', '2019-04-10 20:03:02', '2019-12-03 14:39:36', '# 网易\r\n```\r\ncd /etc/yum.repos.d/\r\nsu\r\nwget http://mirrors.163.com/.help/fedora-163.repo\r\nwget http://mirrors.163.com/.help/fedora-updates-163.repo\r\n```\r\n# 阿里云\r\n第一步:备份你的原镜像文件,以免出错后可以恢复\r\n\r\n```\r\nsudo mv /etc/yum.repos.d/fedora.repo /etc/yum.repos.d/fedora.repo.backup\r\nsudo mv /etc/yum.repos.d/fedora-updates.repo /etc/yum.repos.d/fedora-updates.repo.backup\r\n```\r\n\r\n第二步:下载新的 `fedora.repo` 和 `fedora-updates.repo` 到 `/etc/yum.repos.d/`\r\n\r\n```\r\nsudo wget -O /etc/yum.repos.d/fedora.repo http://mirrors.aliyun.com/repo/fedora.repo\r\nsudo wget -O /etc/yum.repos.d/fedora-updates.repo http://mirrors.aliyun.com/repo/fedora-updates.repo\r\n```\r\n\r\n第三步:运行yum makecache生成缓存\r\n\r\n```\r\ndnf clean all\r\ndnf makecache\r\n```', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7873, '', 'Fedora29 or CentOS7 安装Chrome', '2019-04-10 20:04:11', '2019-05-03 09:47:19', '```\r\nhttps://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm\r\n```\r\n\r\n```\r\nrpm -ivh *.rpm\r\n```', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7874, '', 'Docker容器的导入和导出', '2019-04-14 02:31:25', '2019-12-01 14:43:37', '# 导出Docker容器到本地\r\n```\r\ndocker export docker-centos > centos-with-dev-env.tar\r\n```\r\n\r\n# 导入容器到本地镜像\r\n```\r\ncat centos-with-dev-env.tar | docker import - centos-with-dev-env:1.0.0\r\n```\r\n\r\n# 从网路导入容器到本地镜像\r\n```\r\ndocker import url res:tag\r\n```\r\n\r\nor\r\n\r\n```\r\nPS C:\\Users\\Terwer\\desktop> docker ps -a\r\nCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES\r\n610d84f37881 terwer/centos:7 \"bash /entrypoint.sh\" 8 hours ago Exited (255) 14 minutes ago 0.0.0.0:3000-3001->3000-3001/tcp, 0.0.0.0:5901->5901/tcp, 0.0.0.0:8080-8081->8080-8081/tcp, 0.0.0.0:8090-8091->8090-8091/tcp, 0.0.0.0:9090->9090/tcp docker-centos\r\nPS C:\\Users\\Terwer\\desktop> docker commit 610d84f37881 terwer/centos-with-dev-env:1.0.0\r\n```', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7875, '', 'CentOS 6&7 安装使用多个GCC版本(GCC4.9,GCC5.3,GCC6.2)', '2019-04-17 22:49:33', '2019-12-01 06:49:16', 'CentOS 作为企业级服务器操作系统被广泛使用,其中使用C++开发服务器应用又是常见的,可是CentOS本身自带的GCC版本更新缓慢,要想使用较新的GCC版本就是一个经常需要解决的问题,当然可以自行编译GCC源码,但是比较麻烦,而且很难做到多个GCC版本之间进行切换。\r\n\r\n从CentOS6开始,CentOS自身提供了一种方式可以使用 `Scientific Linux distribution` 发行版的 `devtoolset-*` 来解决。具体使用方式如下:\r\n\r\n1.安装scl发布源:`yum install centos-release-scl-rh`\r\n\r\n2.安装GCC&GCC-C++:`yum install devtoolset-3-gcc devtoolset-3-gcc-c++`\r\n\r\n这里面devtoolset-3是第3个版本,目前针对CentOS6&7支持3,4,6三个版本,分别对应GCC4.9,GCC5.3,GCC6.2,用户可以根据自己的需要选择安装哪一个版本,当然可以同时安装多个版本。\r\n\r\n3.根据需要使用:`source /opt/rh/devtoolset-3/enable` 进行切换,这里面devtoolset-3可以根据你是安装3,4,6进行切换。这个切换原理也很简单,只是设置了一些环境变量。若要在启动的时候就生效,可以放置到~/.bashrc之中即可。\r\n\r\n4.要安装6.2版本,可以yum install devtoolset-6-gcc devtoolset-6-gcc-c++\r\n\r\ndevtoolset-7:对应于gcc7.2\r\n\r\n注意:有些版本的centos可能安装失败,会提示没有6的包,此时先yum remove centos-release-scl-rh,重新执行上述步骤试试。', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7876, '', '使用ss-fly搭建shadowsocks科学上网环境', '2019-04-21 05:32:24', '2019-12-01 23:51:54', '> 2019/04/20 验证通过 \r\n> \r\n```\r\ncd /root\r\ngit clone https://github.com/flyzy2005/ss-fly.git\r\n./ss-fly/ss-fly.sh -i terwergreen.com 1024\r\n```', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7877, '', 'Spring Cloud微服务学习笔记(二):服务注册与发现Eureka', '2019-04-28 19:10:19', '2019-05-01 23:43:47', 'Hello World\r\n\r\nhttps://github.com/terwer/spring-cloud-samples/tree/master/eureka-server\r\n\r\nhttps://github.com/terwer/spring-cloud-samples/tree/master/eureka-client\r\n\r\n# 本系列版本\r\n```xml\r\n1.8\r\nGreenwich.SR1\r\n```\r\n\r\n# 参考\r\n[Spring Cloud in spring.io](https://spring.io/projects/spring-cloud#overview)\r\n\r\n[DDspace](http://blog.didispace.com/spring-cloud-learning/)', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7878, '', 'Spring Cloud微服务学习笔记(一):走进微服务', '2019-04-28 21:02:21', '2019-11-27 22:37:55', '# 前言\r\n本篇文章简单介绍一下什么是微服务、微服务的优点、Spring Cloud的微服务架构核心组件选型等。\r\n\r\n# 一、什么是微服务?\r\n微服务的提出者Martin Fowler是这样描述微服务的(原文:https://martinfowler.com/articles/microservices.html )\r\n\r\n简单来说,微服务架构风格是一种将一个单一应用程序开发为一组小型服务的方法,每个服务运行在自己的进程中,服务间通信采用轻量级通信机制(通常用 HTTP 资源 API )。这些服务围绕业务能力构建并且可通过全自动部署机制独立部署。这些服务共用一个最小型的集中式的管理,服务可用不同的语言开发,使用不同的数据存储技术。\r\n\r\n故微服务架构应具有以下特性:\r\n\r\n* 每个微服务可独立运行在自己的进程里,即独立部署;\r\n\r\n* 一系列独立运行的微服务共同构建起整个系统,即分布式系统架构;\r\n\r\n* 每个服务为独立的业务开发,一个微服务只关注某个特定的功能,即业务服务层的高内聚低耦合,业务的模块化;\r\n\r\n> 微服务之间通过轻量级的通信机制通信,即使用RestFul调用;\r\n\r\n> 可使用不同的语言和数据存储技术;\r\n\r\n* 自动化部署.\r\n\r\n\r\n总结:\r\n\r\n装逼版:微服务,即基于独立的业务模块化单元的单机应用进行的完整、成熟的分布式架构;\r\n\r\n白话版:微服务,即多个微小的独立部署的应用单元组成的,各个服务之间互不影响的一套完整的系统。\r\n\r\n# 参考\r\nhttps://www.cnblogs.com/lfalex0831/p/9139275.html', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7879, '', 'Java闲言碎语', '2019-04-30 17:40:56', '2019-06-20 18:28:57', '1、`ArrayList` 允许存储 `null`,`ArrayList` 与 `Vector` 除了 `ArrayList` 不是线程安全的之外,其他的完全相同。', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7880, '', 'Fedora 30安装Deepin Desktop', '2019-05-01 02:51:44', '2019-11-28 11:18:17', '```\r\nsudo dnf install deepin-desktop -y\r\nsudo dnf install deepin-calendar deepin-calculator deepin-editor deepin-image-viewer deepin-picker deepin-screenshot deepin-system-monitor -y\r\n```\r\n\r\n```\r\nexport GTK_IM_MODULE=ibus\r\nexport XMODIFIERS=@im=ibus\r\nexport QT_IM_MODULE=ibus\r\n```\r\n# 参考\r\n[Feora29安装图形界面](http://www.terwergreen.com/post-dark/7871.html)\r\n\r\n', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7881, '', 'JShell: Finally, an Official Shell in Java 9', '2019-05-06 18:35:59', '2019-12-01 05:47:46', '[https://dzone.com/articles/jshell-finally-an-official-shell-in-java-9](https://dzone.com/articles/jshell-finally-an-official-shell-in-java-9)\r\n\r\nThis breakdown of Java 9\'s new REPL, JShell, shows off all of its features and how you can put it to use in your projects.\r\n\r\nThe shell or the REPL is a well-known tool in many programming languages. Typically, this is more common in scripting languages such as Python or Node, but more recently it’s been adopted by JVM languages like Clojure and Groovy as well. The upcoming Java 9 release finally brings this shell functionality to the Java language as well, in the form of JShell.\r\n\r\nThis article will explore what we can do with JShell and how to make the most of it.\r\n\r\n# What Is a REPL?\r\nSimply put, the REPL is an interactive shell into which we can enter commands and have these immediately executed and the results displayed.\r\n\r\nThe use of this tool tools can greatly help in trying out new ideas and techniques and in quickly testing code without needing to write an entire test class to run.\r\n\r\nAt the core, this is all about an immediate feedback loop and can have a significant impact on productivity in that particular language.\r\n\r\n\r\n', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (7882, '', 'Spring源码深度解析(一)IOC与Spring 核心容器体系结构', '2019-05-07 01:48:07', '2019-11-29 17:22:42', '# IOC是什么\r\n`IOC-Inversion of Control`,即“控制反转”,也叫 `DI-Dependency Injection`,即“依赖注入”,不是什么技术,而是一种设计思想。在Java开发中,`IOC` 意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。\r\n\r\n理解好Ioc的关键是要明确“谁控制谁,控制什么,为何是反转(有反转就应该有正转了),哪些方面反转了”,那我们来深入分析一下:\r\n\r\n* 谁控制谁,控制什么\r\n\r\n传统Java SE程序设计,我们直接在对象内部通过 `new` 进行创建对象,是程序主动去创建依赖对象;而 `IOC` 是有专门一个容器来创建这些对象,即由 `IOC容器` 来控制对象的创建;谁控制谁?当然是IoC容器控制了对象;控制什么?那就是主要控制了外部资源获取(不只是对象包括比如文件等)。\r\n\r\n* 为何是反转,哪些方面反转了\r\n\r\n有反转就有正转,传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转;而反转则是由容器来帮忙创建及注入依赖对象;为何是反转?因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;哪些方面反转了?依赖对象的获取被反转了。\r\n\r\n# IOC和DI\r\n\r\n`DI—Dependency Injection`,即“依赖注入”:是组件之间依赖关系由容器在运行期决定,形象的说,即由容器动态的将某个依赖关系注入到组件之中。依赖注入的目的并非为软件系统带来更多功能,而是为了提升组件重用的频率,并为系统搭建一个灵活、可扩展的平台。通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不需要关心具体的资源来自何处,由谁实现。\r\n\r\n理解DI的关键是:“谁依赖谁,为什么需要依赖,谁注入谁,注入了什么”,那我们来深入分析一下:\r\n\r\n谁依赖于谁:当然是应用程序依赖于IoC容器;\r\n\r\n* 为什么需要依赖:应用程序需要IoC容器来提供对象需要的外部资源;\r\n\r\n* 谁注入谁:很明显是IoC容器注入应用程序某个对象,应用程序依赖的对象;\r\n\r\n* 注入了什么:就是注入某个对象所需要的外部资源(包括对象、资源、常量数据)。\r\n\r\nIoC和DI由什么关系呢?其实它们是同一个概念的不同角度描述,由于控制反转概念比较含糊(可能只是理解为容器控制对象这一个层面,很难让人想到谁来维护对象关系),所以2004年大师级人物Martin Fowler又给出了一个新的名字:“依赖注入”,相对IoC 而言,“依赖注入”明确描述了“被注入对象依赖IoC容器配置依赖对象”。\r\n\r\n# Spring是什么\r\nSpring是一个开源的轻量级Java SE(Java 标准版本)/Java EE(Java 企业版本)开发应用框架,其目的是用于简化企业级应用程序开发。应用程序是由一组相互协作的对象组成。而在传统应用程序开发中,一个完整的应用是由一组相互协作的对象组成。所以开发一个应用除了要开发业务逻辑之外,最多的是关注如何使这些对象协作来完成所需功能,而且要低耦合、高内聚。业务逻辑开发是不可避免的,那如果有个框架出来帮我们来创建对象及管理这些对象之间的依赖关系。可能有人说了,比如“抽象工厂、工厂方法设计模式”不也可以帮我们创建对象,“生成器模式”帮我们处理对象间的依赖关系,不也能完成这些功能吗?可是这些又需要我们创建另一些工厂类、生成器类,我们又要而外管理这些类,增加了我们的负担,如果能有种通过配置方式来创建对象,管理对象之间依赖关系,我们不需要通过工厂和生成器来创建及管理对象之间的依赖关系,这样我们是不是减少了许多工作,加速了开发,能节省出很多时间来干其他事。Spring框架刚出来时主要就是来完成这个功能。\r\n\r\nSpring框架除了帮我们管理对象及其依赖关系,还提供像通用日志记录、性能统计、安全控制、异常处理等面向切面的能力,还能帮我管理最头疼的数据库事务,本身提供了一套简单的JDBC访问实现,提供与第三方数据访问框架集成(如Hibernate、JPA),与各种Java EE技术整合(如Java Mail、任务调度等等),提供一套自己的web层框架Spring MVC、而且还能非常简单的与第三方web框架集成。从这里我们可以认为Spring是一个超级粘合平台,除了自己提供功能外,还提供粘合其他技术和框架的能力,从而使我们可以更自由的选择到底使用什么技术进行开发。而且不管是JAVA SE(C/S架构)应用程序还是JAVA EE(B/S架构)应用程序都可以使用这个平台进行开发。让我们来深入看一下Spring到底能帮我们做些什么?\r\n\r\n# Spring能帮我们做什么\r\nSpring除了不能帮我们写业务逻辑,其余的几乎什么都能帮助我们简化开发:\r\n\r\n一、传统程序开发,创建对象及组装对象间依赖关系由我们在程序内部进行控制,这样会加大各个对象间的耦合,如果我们要修改对象间的依赖关系就必须修改源代码,重新编译、部署;而如果采用Spring,则由Spring根据配置文件来进行创建及组装对象间依赖关系,只需要改配置文件即可,无需重新编译。所以,Spring能帮我们根据配置文件创建及组装对象之间的依赖关系。\r\n\r\n二、当我们要进行一些日志记录、权限控制、性能统计等时,在传统应用程序当中我们可能在需要的对象或方法中进行,而且比如权限控制、性能统计大部分是重复的,这样代码中就存在大量重复代码,即使有人说我把通用部分提取出来,那必然存在调用还是存在重复,像性能统计我们可能只是在必要时才进行,在诊断完毕后要删除这些代码;还有日志记录,比如记录一些方法访问日志、数据访问日志等等,这些都会渗透到各个要访问方法中;还有权限控制,必须在方法执行开始进行审核,想想这些是多么可怕而且是多么无聊的工作。如果采用Spring,这些日志记录、权限控制、性能统计从业务逻辑中分离出来,通过Spring支持的面向切面编程,在需要这些功能的地方动态添加这些功能,无需渗透到各个需要的方法或对象中;有人可能说了,我们可以使用“代理设计模式”或“包装器设计模式”,你可以使用这些,但还是需要通过编程方式来创建代理对象,还是要耦合这些代理对象,而采用Spring 面向切面编程能提供一种更好的方式来完成上述功能,一般通过配置方式,而且不需要在现有代码中添加任何额外代码,现有代码专注业务逻辑。所以,Spring 面向切面编程能帮助我们无耦合的实现日志记录,性能统计,安全控制。\r\n\r\n三、在传统应用程序当中,我们如何来完成数据库事务管理?需要一系列“获取连接,执行SQL,提交或回滚事务,关闭连接”,而且还要保证在最后一定要关闭连接,多么可怕的事情,而且也很无聊;如果采用Spring,我们只需获取连接,执行SQL,其他的都交给Spring来管理了,简单吧。所以,Spring能非常简单的帮我们管理数据库事务。\r\n\r\n四、Spring还提供了与第三方数据访问框架(如Hibernate、JPA)无缝集成,而且自己也提供了一套JDBC访问模板,来方便数据库访问。\r\n\r\n五、Spring还提供与第三方Web(如Struts、JSF)框架无缝集成,而且自己也提供了一套Spring MVC框架,来方便web层搭建。\r\n\r\n六、Spring能方便的与Java EE(如Java Mail、任务调度)整合,与更多技术整合(比如缓存框架)。\r\n\r\nSpring能帮我们做这么多事情,提供这么多功能和与那么多主流技术整合,而且是帮我们做了开发中比较头疼和困难的事情,那可能有人会问,难道只有Spring这一个框架,没有其他选择?当然有,比如EJB需要依赖应用服务器、开发效率低、在开发中小型项目是宰鸡拿牛刀,虽然发展到现在EJB比较好用了,但还是比较笨重还需要依赖应用服务器等。那为何需要使用Spring,而不是其他框架呢?让我们接着往下看。\r\n\r\n# 为何需要Spring\r\n一 首先阐述几个概念\r\n1、应用程序:是能完成我们所需要功能的成品,比如购物网站、OA系统。\r\n\r\n2、框架:是能完成一定功能的半成品,比如我们可以使用框架进行购物网站开发;框架做一部分功能,我们自己做一部分功能,这样应用程序就创建出来了。而且框架规定了你在开发应用程序时的整体架构,提供了一些基础功能,还规定了类和对象的如何创建、如何协作等,从而简化我们开发,让我们专注于业务逻辑开发。\r\n\r\n3、非侵入式设计:从框架角度可以这样理解,无需继承框架提供的类,这种设计就可以看作是非侵入式设计,如果继承了这些框架类,就是侵入设计,如果以后想更换框架之前写过的代码几乎无法重用,如果非侵入式设计则之前写过的代码仍然可以继续使用。\r\n\r\n4、轻量级及重量级:轻量级是相对于重量级而言的,轻量级一般就是非入侵性的、所依赖的东西非常少、资源占用非常少、部署简单等等,其实就是比较容易使用,而重量级正好相反。\r\n\r\n5、POJO:POJO(Plain Old Java Objects)简单的Java对象,它可以包含业务逻辑或持久化逻辑,但不担当任何特殊角色且不继承或不实现任何其它Java框架的类或接口。\r\n\r\n6、容器:在日常生活中容器就是一种盛放东西的器具,从程序设计角度看就是装对象的的对象,因为存在放入、拿出等操作,所以容器还要管理对象的生命周期。\r\n\r\n7、控制反转:即Inversion of Control,缩写为IoC,控制反转还有一个名字叫做依赖注入(Dependency Injection),就是由容器控制程序之间的关系,而非传统实现中,由程序代码直接操控。\r\n\r\n8、Bean:一般指容器管理对象,在Spring中指Spring IoC容器管理对象。\r\n\r\n# Spring的优点\r\n\r\n* 非常轻量级的容器:以集中的、自动化的方式进行应用程序对象创建和装配,负责对象创建和装配,管理对象生命周期,能组合成复杂的应用程序。Spring容器是非侵入式的(不需要依赖任何Spring特定类),而且完全采用POJOs进行开发,使应用程序更容易测试、更容易管理。而且核心JAR包非常小,Spring3.0.5不到1M,而且不需要依赖任何应用服务器,可以部署在任何环境(Java SE或Java EE)。\r\n\r\n* AOP:AOP是Aspect Oriented Programming的缩写,意思是面向切面编程,提供从另一个角度来考虑程序结构以完善面向对象编程(相对于OOP),即可以通过在编译期间、装载期间或运行期间实现在不修改源代码的情况下给程序动态添加功能的一种技术。通俗点说就是把可重用的功能提取出来,然后将这些通用功能在合适的时候织入到应用程序中;比如安全,日记记录,这些都是通用的功能,我们可以把它们提取出来,然后在程序执行的合适地方织入这些代码并执行它们,从而完成需要的功能并复用了这些功能。\r\n\r\n* 简单的数据库事务管理:在使用数据库的应用程序当中,自己管理数据库事务是一项很让人头疼的事,而且很容易出现错误,Spring支持可插入的事务管理支持,而且无需JEE环境支持,通过Spring管理事务可以把我们从事务管理中解放出来来专注业务逻辑。\r\n\r\n* JDBC抽象及ORM框架支持:Spring使JDBC更加容易使用;提供DAO(数据访问对象)支持,非常方便集成第三方ORM框架,比如Hibernate等;并且完全支持Spring事务和使用Spring提供的一致的异常体系。\r\n\r\n* 灵活的Web层支持:Spring本身提供一套非常强大的MVC框架,而且可以非常容易的与第三方MVC框架集成,比如Struts等。\r\n\r\n* 简化各种技术集成:提供对Java Mail、任务调度、JMX、JMS、JNDI、EJB、动态语言、远程访问、Web Service等的集成。\r\n\r\nSpring能帮助我们简化应用程序开发,帮助我们创建和组装对象,为我们管理事务,简单的MVC框架,可以把Spring看作是一个超级粘合平台,能把很多技术整合在一起,形成一个整体,使系统结构更优良、性能更出众,从而加速我们程序开发,有如上优点,我们没有理由不考虑使用它。\r\n\r\n# Spring架构图\r\n\r\n![](https://terwer.oss-cn-qingdao.aliyuncs.com/bugucms/spring.jpg)\r\n\r\n核心容器:包括Core、Beans、Context、EL模块。\r\n\r\n●Core模块:封装了框架依赖的最底层部分,包括资源访问、类型转换及一些常用工具类。\r\n\r\n●Beans模块:提供了框架的基础部分,包括反转控制和依赖注入。其中Bean Factory是容器核心,本质是“工厂设计模式”的实现,而且无需编程实现“单例设计模式”,单例完全由容器控制,而且提倡面向接口编程,而非面向实现编程;所有应用程序对象及对象间关系由框架管理,从而真正把你从程序逻辑中把维护对象之间的依赖关系提取出来,所有这些依赖关系都由BeanFactory来维护。\r\n\r\n●Context模块:以Core和Beans为基础,集成Beans模块功能并添加资源绑定、数据验证、国际化、Java EE支持、容器生命周期、事件传播等;核心接口是ApplicationContext。\r\n\r\n●EL模块:提供强大的表达式语言支持,支持访问和修改属性值,方法调用,支持访问及修改数组、容器和索引器,命名变量,支持算数和逻辑运算,支持从Spring 容器获取Bean,它也支持列表投影、选择和一般的列表聚合等。\r\n\r\nAOP、Aspects模块:\r\n\r\n●AOP模块:Spring AOP模块提供了符合 AOP Alliance规范的面向方面的编程(aspect-oriented programming)实现,提供比如日志记录、权限控制、性能统计等通用功能和业务逻辑分离的技术,并且能动态的把这些功能添加到需要的代码中;这样各专其职,降低业务逻辑和通用功能的耦合。\r\n\r\n●Aspects模块:提供了对AspectJ的集成,AspectJ提供了比Spring ASP更强大的功能。\r\n\r\n数据访问/集成模块:该模块包括了JDBC、ORM、OXM、JMS和事务管理。\r\n\r\n●事务模块:该模块用于Spring管理事务,只要是Spring管理对象都能得到Spring管理事务的好处,无需在代码中进行事务控制了,而且支持编程和声明性的事物管理。\r\n\r\n●JDBC模块:提供了一个JBDC的样例模板,使用这些模板能消除传统冗长的JDBC编码还有必须的事务控制,而且能享受到Spring管理事务的好处。\r\n\r\n●ORM模块:提供与流行的“对象-关系”映射框架的无缝集成,包括Hibernate、JPA、Ibatiss等。而且可以使用Spring事务管理,无需额外控制事务。\r\n\r\n●OXM模块:提供了一个对Object/XML映射实现,将java对象映射成XML数据,或者将XML数据映射成java对象,Object/XML映射实现包括JAXB、Castor、XMLBeans和XStream。\r\n\r\n●JMS模块:用于JMS(Java Messaging Service),提供一套 “消息生产者、消息消费者”模板用于更加简单的使用JMS,JMS用于用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。\r\n\r\n●Web/Remoting模块:Web/Remoting模块包含了Web、Web-Servlet、Web-Struts、Web-Porlet模块。\r\n\r\n●Web模块:提供了基础的web功能。例如多文件上传、集成IoC容器、远程过程访问(RMI、Hessian、Burlap)以及Web Service支持,并提供一个RestTemplate类来提供方便的Restful services访问。\r\n\r\n●Web-Servlet模块:提供了一个Spring MVC Web框架实现。Spring MVC框架提供了基于注解的请求资源注入、更简单的数据绑定、数据验证等及一套非常易用的JSP标签,完全无缝与Spring其他技术协作。\r\n\r\n●Web-Struts模块:提供了与Struts无缝集成,Struts1.x 和Struts2.x都支持\r\n\r\nTest模块: Spring支持Junit和TestNG测试框架,而且还额外提供了一些基于Spring的测试功能,比如在测试Web框架时,模拟Http请求的功能。\r\n\r\n# 参考\r\n[https://blog.csdn.net/lj1314ailj/article/details/80352054](https://blog.csdn.net/lj1314ailj/article/details/80352054)\r\n\r\n', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7883, '', 'Spring源码深度解析(二) IOC 容器的初始化(一)', '2019-05-07 02:58:26', '2019-09-01 00:11:09', '让他', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7884, '', 'Apache Dubbo学习笔记(一)初识Dubbo', '2019-05-13 21:53:33', '2019-11-28 05:30:06', '# Dubbo是什么\r\ndubbo 是一个基于 `Java` 的、高性能、开源的 [`RPC`](https://www.zhihu.com/question/25536695/answer/36197244) 框架。\r\n\r\n# Dubbo的主要功能\r\n\r\ndubbo 提供了3个主要功能:\r\n\r\n* 远程接口调用\r\n\r\n* 容错与负载均衡\r\n\r\n* 自动服务注册与发现\r\n\r\n![](https://terwer.oss-cn-qingdao.aliyuncs.com/bugucms/dubbo-architecture.png)\r\n\r\n# dubbo的特特性\r\n* 透明化的 `RPC` 接口\r\n\r\ndubbo 提供的高性能的 `RPC` ,对用户是透明的。\r\n\r\n* 智能负载均衡\r\n\r\ndubbo 支持多种负载均衡策略,能察觉服务状态,减少延迟,提高吞吐量。\r\n\r\n* 自动服务注册与发现\r\n\r\ndubbo 支持多种服务注册方式,能实时发现服务在线与离线。\r\n\r\n* 高可扩展性\r\n\r\ndubbo 的微内核和插件设计保证了它很容易通过协议、传输和序列化来扩展第三方实现。\r\n\r\n* 运行时路由\r\n\r\ndubbo 能在运行时配置通过不同规则路由,使得它很容易支持蓝绿部署 [ blue-green deployment](http://www.cnblogs.com/chenliangcl/chenliangcl/p/10142241.html)\r\n\r\n、数据中心路由(data center aware routing)。\r\n\r\n* 可视化服务管理\r\n\r\ndubbo 提供了丰富的组件用于服务管理和维护,例如服务元数据查询、健康状态和数据统计等等。\r\n\r\n# 参考\r\n\r\n[http://dubbo.incubator.apache.org/en-us/](http://dubbo.incubator.apache.org/en-us/)\r\n', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7885, '', 'Spring源码深度解析(二)实现IOC的几种方式', '2019-05-21 19:34:14', '2019-12-03 04:45:34', '# 项目结构\r\n\r\n```\r\n├── iocinit.iml\r\n├── pom.xml\r\n├── src\r\n│   ├── main\r\n│   │   ├── java\r\n│   │   │   └── com\r\n│   │   │   └── terwergreen\r\n│   │   │   └── spring\r\n│   │   │   └── iocinit\r\n│   │   │   ├── IOCTest1.java\r\n│   │   │   ├── IOCTest2.java\r\n│   │   │   ├── IOCTest3.java\r\n│   │   │   └── beans\r\n│   │   │   ├── America.java\r\n│   │   │   ├── Chinese.java\r\n│   │   │   └── Person.java\r\n│   │   └── resources\r\n│   │   └── applicationContext.xml\r\n│   └── test\r\n│   └── java\r\n```\r\n# pom.xml\r\n\r\n```\r\n\r\n\r\n 4.0.0\r\n\r\n com.terwergreen.spring\r\n iocinit\r\n 1.0.0\r\n\r\n \r\n \r\n \r\n org.springframework\r\n spring-beans\r\n 5.1.6.RELEASE\r\n \r\n \r\n \r\n org.springframework\r\n spring-context\r\n 5.1.6.RELEASE\r\n \r\n \r\n\r\n```\r\n\r\n# beans\r\n\r\n先建立几个bean\r\n\r\n`America.java`\r\n\r\n```\r\npackage com.terwergreen.spring.iocinit.beans;\r\n\r\npublic class America implements Person {\r\n public String sayHello(String name) {\r\n return \"hello,\" + name;\r\n }\r\n}\r\n```\r\n\r\n`Chinese.java`\r\n\r\n```\r\npackage com.terwergreen.spring.iocinit.beans;\r\n\r\n/**\r\n * Chinese\r\n *\r\n * @author Terwer\r\n * @version 1.0\r\n * 2019/5/6 17:39\r\n **/\r\npublic class Chinese implements Person {\r\n public String sayHello(String name) {\r\n return \"你好,\" + name;\r\n }\r\n}\r\n```\r\n\r\n`Person.java`\r\n\r\n```\r\npackage com.terwergreen.spring.iocinit.beans;\r\n\r\n/**\r\n * Person\r\n *\r\n * @author Terwer\r\n * @version 1.0\r\n * 2019/5/6 17:39\r\n **/\r\npublic interface Person {\r\n String sayHello(String name);\r\n}\r\n```\r\n\r\n# 使用 `XmlBeanFactory` 实现IOC\r\n\r\n```\r\npackage com.terwergreen.spring.iocinit;\r\n\r\nimport com.terwergreen.spring.iocinit.beans.Person;\r\nimport org.springframework.beans.factory.xml.XmlBeanFactory;\r\nimport org.springframework.core.io.ClassPathResource;\r\n\r\n/**\r\n * IOCTest1\r\n *\r\n * @author terwer\r\n * @version 1.0\r\n * 2019-05-17 21:38\r\n **/\r\npublic class IOCTest1 {\r\n\r\n public static void main(String[] args) {\r\n ClassPathResource resource = new ClassPathResource(\"applicationContext.xml\");\r\n XmlBeanFactory beanFactory = new XmlBeanFactory(resource);\r\n Person p1 = (Person) beanFactory.getBean(\"chinese\");\r\n String result = p1.sayHello(\"Terwer\");\r\n System.out.println(result);\r\n\r\n Person p2 = (Person) beanFactory.getBean(\"america\");\r\n String result2 = p2.sayHello(\"Green\");\r\n System.out.println(result2);\r\n\r\n }\r\n}\r\n```\r\n输出\r\n\r\n```\r\n你好,Terwer\r\nhello,Green\r\n```\r\n\r\n# 使用 `DefaultListableBeanFactory` 实现IOC\r\n\r\n```\r\npackage com.terwergreen.spring.iocinit;\r\n\r\nimport com.terwergreen.spring.iocinit.beans.Person;\r\nimport org.springframework.beans.factory.support.DefaultListableBeanFactory;\r\nimport org.springframework.beans.factory.xml.XmlBeanDefinitionReader;\r\nimport org.springframework.core.io.ClassPathResource;\r\n\r\n/**\r\n * IOCTest2\r\n *\r\n * @author terwer\r\n * @version 1.0\r\n * 2019-05-17 21:45\r\n **/\r\npublic class IOCTest2 {\r\n\r\n public static void main(String[] args) {\r\n // 定位\r\n ClassPathResource resource = new ClassPathResource(\"applicationContext.xml\");\r\n // 载入\r\n DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();\r\n XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);\r\n // 注册\r\n reader.loadBeanDefinitions(resource);\r\n\r\n // 从beanFactory获取bean\r\n Person p1 = (Person) beanFactory.getBean(\"chinese\");\r\n String result = p1.sayHello(\"Green\");\r\n System.out.println(result);\r\n }\r\n}\r\n```\r\n\r\n输出\r\n\r\n```\r\n你好,Green\r\n```\r\n\r\n# 使用 `ClassPathXmlApplicationContext` 实现IOC\r\n\r\n```\r\npackage com.terwergreen.spring.iocinit;\r\n\r\nimport com.terwergreen.spring.iocinit.beans.Person;\r\nimport org.springframework.context.ApplicationContext;\r\nimport org.springframework.context.support.ClassPathXmlApplicationContext;\r\n\r\n/**\r\n * IOCTest3\r\n *\r\n * @author terwer\r\n * @version 1.0\r\n * 2019-05-17 21:47\r\n **/\r\npublic class IOCTest3 {\r\n public static void main(String[] args) {\r\n ApplicationContext applicationContext = new ClassPathXmlApplicationContext(\"applicationContext.xml\");\r\n\r\n Person p1 = (Person) applicationContext.getBean(\"america\");\r\n String result = p1.sayHello(\"Test3 from applicationContext\");\r\n System.out.println(result);\r\n }\r\n}\r\n```\r\n\r\n输出\r\n\r\n```\r\nhello,Test3 from applicationContext\r\n```', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7886, '', '消息队列之Kafka(一)kafka概述', '2019-05-22 18:39:23', '2019-06-17 21:17:17', '# 背景\r\n消息队列是⽬前各⼤互联⽹公司都在⼤量采⽤且起到坚实作⽤的⼀个中间件产品,⽆论是国内还是国外的公司,消息队列的使⽤都是极为⼴泛的。因此,如果现在对消息队列还是不太熟悉,那我觉得是时候该夯实⾃⼰的基础了。\r\n\r\n# 消息队列产品\r\n\r\n说到消息队列,⽬前存在各种各样的产品,如ActiveMQ、RocketMQ、ZeroMQ、RabbitMQ、Kafka等等等等。⾯对如此之多的消息队列产品,难道我们都需要每个都学习⼀遍么?显然不是这样的。技术⾸先要精准掌握⼀个,然后在横向展开,这样才能取得最佳的效果,也能达到最⾼的学习与使⽤效率。\r\n\r\n# kafka版本\r\n⽬前,Kafka已经在国内外诸多的互联⽹公司与⼤型企业中得到了⼴泛的使⽤。它是由LinkedIn公司开发出来的,⽽后捐赠给了Apache软件基⾦会,并在Apache孵化器中不断成⻓,最终成为了Apache的顶级项⽬。Kafka的版本号⼀直以来都是0.x的,直到去年11⽉份,Kafka 1.0终于发布,这也标志着Kafka真正⾛向了成熟。', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7887, '', '消息队列之Kafka(二)Kafka⼊⻔指引与重要操作', '2019-05-22 18:55:12', '2019-12-01 20:35:48', '⼀开始,我们要做的就是输出『Hello World』,即先将程序运⾏起来,⽤最简单的⽅式得到我们想要看到的最直观的结果,为后续学习开⼀个好头。\r\n\r\nKafka的官⽹是 [http://kafka.apache.org](http://kafka.apache.org) ⾸先访问该⽹址进⼊到Kafka的官⽅⽹站。\r\n\r\n![](https://terwer.oss-cn-qingdao.aliyuncs.com/bugucms/20190522105652.png)', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7888, '', 'JAVA SE Lesson 1', '2019-11-27 23:00:47', '2019-11-29 01:11:51', '1.类是一种抽象的概念,对象是类的一种具体表示形式,是具体的概念。先有类,然后由类来生成对象(Object)。对象又叫做实例(Instance)。\r\n\r\n2.类由两大部分构成:属性以及方法。属性一般用名词来表示, 方法一般用动词来表示。\r\n\r\n3.如果一个 java 源文件中定义了多个类,那么这些类中最多只能有一个类是 public 的,换句话说,定义的多个类可以都不是public 的。\r\n\r\n4.在 Java 中进行方法的参数传递时,无论传递的是原生数据类型还是引用类型,参数传递方式统一是传值(pass by value)。 Java 中没有传引用(pass by reference)的概念。\r\n\r\n5.方法重载(Overload)。表示两个或多个方法名字相同,但方法参数不同。方法参数不同有两层含义:1)参数个数不同。2)参数类型不同。 注意:方法的返回值对重载没有任何影响。\r\n\r\n6.构造方法重载:只需看参数即可。如果想在一个构造方法中调用另外一个构造方法,那么可以使用 this()的方式调用,this()括号中的参数表示目标构造方法的参数。this()必须要作为构造方法的第一条语句,换句话说,this()之前不能有任何可执行的代码。\r\n\r\n7.继承(Inheritence):Java 是单继承的,意味着一个类只能从\r\n\r\n另一个类继承(被继承的类叫做父类【基类,base class】, 继承的类叫做子类),Java 中的继承使用 extends 关键字。\r\n\r\n8.当生成子类对象时,Java 默认首先调用父类的不带参数的构造方法,然后执行该构造方法,生成父类的对象。接下来,再去调用子类的构造方法,生成子类的对象。【要想生成子类的对象,首先需要生成父类的对象,没有父类对象就没有子类对象。比如说:没有父亲,就没有孩子】。\r\n\r\n9.super 关键字:super 表示对父类对象的引用。\r\n\r\n10.如果子类使用 super()显式调用父类的某个构造方法,那么在执行的时候就会寻找与 super()所对应的构造方法而不会再去寻找父类的不带参数的构造方法。与this 一样,super 也必须要作为构造方法的第一条执行语句,前面不能有其他可执行语句。\r\n\r\n11.关于继承的 3 点:\r\n\r\na)父类有的,子类也有 \r\nb)父类没有的,子类可以增加 \r\nc)父类有的,子类可以改变 \r\n\r\n12.关于继承的注意事项\r\n\r\na)构造方法不能被继承 \r\nb)方法和属性可以被继承 \r\nc)子类的构造方法隐式地调用父类的不带参数的构造方法 \r\nd)当父类没有不带参数的构造方法时,子类需要使用 super 来显式地调用父类的构造方法,super 指的是对父类的引用 \r\ne)super 关键字必须是构造方法中的第一行语句。\r\n\r\n13.方法重写(Override):又叫做覆写,子类与父类的方法返回类型一样、方法名称一样,参数一样,这样我们说子类与父类的方法构成了重写关系。\r\n\r\n14.方法重写与方法重载之间的关系:重载发生在同一个类内部的两个或多个方法。重写发生在父类与子类之间。\r\n\r\n15.当两个方法形成重写关系时, 可以在子类方法中通过super.run()形式调用父类的 run()方法,其中 super.run()不必放在第一行语句,因此此时父类对象已经构造完毕,先调用父类的run()方法还是先调用子类的run()方法是根据程序的逻辑决定的。\r\n\r\n16.在定义一个类的时候,如果没有显式指定该类的父类,那么该类就会继承于 java.lang.Object 类(JDK 提供的一个类,Object类是Java 中所有类的直接或间接父类)。\r\n\r\n17.多态(Polymorphism):我们说子类就是父类(玫瑰是花,男人是人),因此多态的意思就是:父类型的引用可以指向子类的对象。', 1, 0, NULL, NULL, 'publish', 'note', 1, 0); +INSERT INTO `posts` VALUES (7890, '', 'Java SE Lesson 2', '2019-11-28 00:48:17', '2019-12-03 17:21:33', '1.多态:父类型的引用可以指向子类型的对象。\r\n\r\n2.Parent p = new Child();当使用多态方式调用方法时,首先检查父类中是否有sing()方法,如果没有则编译错误;如果有,再去调用子类的 sing()方法。\r\n\r\n3.一共有两种类型的强制类型转换:\r\n\r\na)向上类型转换(upcast):比如说将 Cat 类型转换为 Animal 类型,即将子类型转换为父类型。对于向上类型转换,不需要显式指定。 \r\nb)向下类型转换(downcast):比如将 Animal 类型转换为 Cat 类型。即将父类型转换为子类型。对于向下类型转换,必须要显式指定(必须要使用强制类型转换)。\r\n\r\n4.抽象类(abstract class):使用了 abstract 关键字所修饰的 类叫做抽象类。抽象类无法实例化,也就是说,不能 new 出来一个抽象类的对象(实例)。\r\n\r\n5.抽象方法(abstract method):使用 abstract 关键字所修饰的方法叫做抽象方法。抽象方法需要定义在抽象类中。相对于抽象方法,之前所定义的方法叫做具体方法(有声明,有实现)。\r\n\r\n6.如果一个类包含了抽象方法,那么这个类一定是抽象类。\r\n\r\n7.如果某个类是抽象类,那么该类可以包含具体方法(有声明、有实现)。\r\n\r\n8.如果一个类中包含了抽象方法,那么这个类一定要声明成 abstract class,也就是说,该类一定是抽象类;反之,如果某个类是抽象类,那么该类既可以包含抽象方法,也可以包含具体方法。\r\n\r\n9.无论何种情况,只要一个类是抽象类,那么这个类就无法实例化。\r\n\r\n10. 在子类继承父类(父类是个抽象类)的情况下,那么该子类必须要实现父类中所定义的所有抽象方法;否则,该子类需要声明成一个 abstract class。\r\n\r\n11. 接口(interface):接口的地位等同于 class,接口中的所有方法都是抽象方法。在声明接口中的方法时,可以使用 abstract 关键字,也可以不使用。通常情况下,都会省略掉 abstract 关键字。\r\n\r\n12.可以将接口看作是特殊的抽象类(抽象类中可以有具体方法,也可以有抽象方法,而接口中只能有抽象方法,不能有具体方法)。\r\n\r\n13. 类可以实现接口。实现使用关键字 implements 表示,代表了某个类实现了某个接口。\r\n\r\n14.一个类实现了某个接口,那么该类必须要实现接口中声明的所有方法。如果该类是个抽象类,那么就无需实现接口中的方法了。\r\n\r\n15.Java 是单继承的,也就是说某个类只能有唯一一个父类;一个类可以实现多个接口,多个接口之间使用逗号分隔。\r\n\r\n16. 多态:所谓多态,就是父类型的引用可以指向子类型的对象,或者接口类型的引用可以指向实现该接口的类的实例。关于接口与实现接口的类之间的强制类型转换方式与父类和子类之间的强制类型转换方式完全一样。\r\n\r\n17. static 关键字:可以用于修饰属性,也可以用于修饰方法,还可以用于修饰类(后面的课程讲)\r\n\r\n18. static 修饰属性:无论一个类生成了多少个对象,所有这些对象共同使用唯一一份静态的成员变量;一个对象对该静态成员变量进行了修改,其他对象的该静态成员变量的值也会随之发生变化。如果一个成员变量是 static 的,\r\n\r\n那么我们可以通过类名.成员变量名的方式来使用它(推荐使用这种方式)。\r\n\r\n19.static 修饰方法:static 修饰的方法叫做静态方法。对于静态方法来说,可以使用类名.方法名的方式来访问。\r\n\r\n20.静态方法只能继承,不能重写(Override)。\r\n\r\n21.final 关键字:final 可以修饰属性、方法、类。\r\n\r\n22.final 修饰类:当一个类被 final 所修饰时,表示该类是一个终态类,即不能被继承。\r\n\r\n23.final 修饰方法:当一个方法被 final 所修饰时,表示该方法是一个终态方法, 即不能被重写(Override)。\r\n\r\n24.final 修饰属性:当一个属性被 final 所修饰时,表示该属性不能被改写。\r\n\r\n25.当 final 修饰一个原生数据类型时,表示该原生数据类型的值不能发生变化\r\n(比如说不能从 10 变为 20);如果 final 修饰一个引用类型时,表示该引用类型不能再指向其他对象了,但该引用所指向的对象的内容是可以发生变化的。\r\n\r\n26.对于 final 类型成员变量,一般来说有两种赋初值方式:\r\n\r\na)在声明 final 类型的成员变量时就赋上初值 \r\nb)在声明 final 类型的成员变量时不赋初值,但在类的所有构造方法中都为其赋上初值。\r\n\r\n27.static 代码块:静态代码块。静态代码块的作用也是完成一些初始化工作。首先执行静态代码块,然后执行构造方法。静态代码块在类被加载的时候执行, 而构造方法是在生成对象的时候执行;要想调用某个类来生成对象,首先需要将类加载到 Java 虚拟机上(JVM),然后由 JVM 加载这个类来生成对象。\r\n\r\n28.类的静态代码块只会执行一次,是在类被加载的时候执行的,因为每个类只会被加载一次,所以静态代码块也只会被执行一次;而构造方法则不然,每次生成一个对象的时候都会调用类的构造方法,所以 new 一次就会调用构造方法一次。\r\n\r\n29.如果继承体系中既有构造方法,又有静态代码块,那么首先执行最顶层的类的静态代码块,一直执行到最底层类的静态代码块,然后再去执行最顶层类的构造方法,一直执行到最底层类的构造方法。注意:静态代码块只会执行一次。\r\n\r\n30.不能在静态方法中访问非静态成员变量;可以在静态方法中访问静态的成员变量。可以在非静态方法中访问静态的成员变量。\r\n\r\n31.总结:静态的只能访问静态的;非静态的可以访问一切。\r\n\r\n32.不能在静态方法中使用 this 关键字。', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7891, '', 'Java SE Lesson 3', '2019-11-28 21:46:39', '2019-11-28 22:12:43', '1.接口中所声明的方法都是抽象方法。接口中的方法都是 public 的。\r\n\r\n2.接口中也可以定义成员变量。接口中的成员变量都是 public、final、static 的。\r\n\r\n3.一个类不能既是 final,又是 abstract 的。因为 abstract 的主要目的是定义一种约定, 让子类去实现这种约定,而 final 表示该类不能被继承,这样 abstract 希望该类可以被继承而 final 明确说明该类不能被继承,两者矛盾。因此一个类不能既是 final 的, 又是 abstract 的。\r\n\r\n4.Design Pattern(设计模式)。单例模式(Singleton):表示一个类只会生成唯一的一个对象。\r\n\r\n5.包(package)。用于将完成不同功能的类分门别类,放在不同的目录(包)下。包的命名规则:将公司域名反转作为包名。www.shengsiyuan.com,com.shengsiyuan(包名),对于包名:每个字母都需要小写。如果定义类的时候没有使用 package,那么 Java 就认为我们所定义的类位于默认包里面(default package)。\r\n\r\n6.编译带有 package 声明的Java 源文件有两种方式:\r\n\r\na)直接编译,然后根据类中所定义的包名,逐一手工建立目录结构,最后将生成的 class\r\n文件放到该目录结构中(很少使用,比较麻烦)。 \r\nb)使用编译参数 –d,方式为 javac –d . 源文件.java,这样在编译后,编译器会自动帮助我们建立好包所对应的目录结构。 \r\n\r\n7.有两个包名,分别是 aa.bb.cc 与 aa.bb.cc.dd,那么我们称后者为前者的子包。\r\n\r\n8.导入(import),将使用 package 分离的各个类导入回来,让编译器能够找到所需要的类。\r\n\r\n9.import 的语法:import com.shengsiyuan.PackageTest;\r\n\r\n10.import com.shengsiyuan.*,表示导入 com.shengsiyuan 包下面的所有类。\r\n\r\n11.import aa.bb.*并不会导入 aa.bb.cc 包下面的类。这时需要这样写:\r\n\r\nimport aa.bb.*; import aa.bb.cc.*;\r\n\r\n12.关于 package、import、class 的顺序问题:\r\n\r\na)首先需要定义包(package),可选 \r\nb)接下来使用 import 进行导入,可选 \r\nc)然后才是class 或 interface 的定义。 \r\n\r\n13.如果两个类在同一个包下面,那么则不需要导入,直接使用即可。\r\n\r\n14.访问修饰符(access modifier)。\r\n\r\n1)public(公共的):被 public 所修饰的属性和方法可以被所有类访问。 \r\n2)protected(受保护的):被 protected 所修饰的属性和方法可以在类内部、相同包以及该类的子类所访问。 \r\n3)private(私有的):被 private 所修饰的属性和方法只能在该类内部使用\r\n\r\n4)默认的(不加任何访问修饰符):在类内部以及相同包下面的类所使用。\r\n\r\n15. instanceof: 判断某个对象是否是某个类的实例。语法形式:引用名 instanceof 类名(接口名),返回一个 boolean 值。\r\n\r\n16.People people = new Man();\r\n\r\n17. System.out.println(people instanceof People); //结果为 true,因为 Man 是People 的子类,根据继承,子类就是父类,因此 Man 也可以看作是People 的实例。\r\n\r\n18.相等性的比较(==)\r\n \r\n1)对于原生数据类型来说,比较的是左右两边的值是否相等。 \r\n2)对于引用类型来说,比较左右两边的引用是否指向同一个对象,或者说左右两边的引用地址是否相同。\r\n\r\n19. java.lang.Object 类。java.lang 包在使用的时候无需显式导入,编译时由编译器自动帮助我们导入。\r\n\r\n20.API (Application Programming Interface),应用编程接口。\r\n\r\n21.当打印引用时,实际上会打印出引用所指对象的 toString()方法的返回值,因为每个类都直接或间接地继承自 Object,而 Object 类中定义了 toString(),因此每个类都有toString()这个方法。\r\n\r\n22.关于进制的表示:16 进制,逢 16 进一,16 进制的数字包括:0~9,A,B,C,D,E,F,\r\n\r\n23.equals()方法,该方法定义在 Object 类当中,因此 Java 中的每个类都具有该方法, 对于 Object 类的 equals()方法来说,它是判断调用 equals()方法的引用与传进来的引用是否一致,即这两个引用是否指向的是同一个对象。对于 Object 类的 equals()方法来说,它等价于==。\r\n\r\n24.对于 String 类的 equals()方法来说,它是判断当前字符串与传进来的字符串的内容是否一致。\r\n\r\n25.对于 String 对象的相等性判断来说,请使用 equals()方法,而不要使用==。\r\n\r\n26.String 是常量,其对象一旦创建完毕就无法改变。当使用+拼接字符串时,会生成新的 String 对象,而不是向原有的 String 对象追加内容。\r\n\r\n27.String Pool(字符串池)\r\n\r\n28.String s = “aaa”;(采用字面值方式赋值)\r\n\r\n1)查找 String Pool 中是否存在“aaa”这个对象,如果不存在,则在 String Pool 中创建一个“aaa”对象,然后将 String Pool 中的这个“aaa”对象的地址返回来,赋给引用变量 s,这样 s 会指向 String Pool 中的这个“aaa”字符串对象 \r\n2)如果存在,则不创建任何对象,直接将 String Pool 中的这个“aaa”对象地址返回来, 赋给 s 引用。\r\n\r\n29.String s = new String(“aaa”);\r\n\r\n1)首先在 String Pool 中查找有没有“aaa”这个字符串对象,如果有,则不在 String Pool 中再去创建“aaa”这个对象了,直接在堆中(heap)中创建一个“aaa”字符串对象,然后将堆中的这个“aaa”对象的地址返回来,赋给 s 引用,导致 s 指向了堆中创建的这个“aaa”字符串对象。 \r\n2)如果没有,则首先在 String Pool 中创建一个“aaa“对象,然后再在堆中(heap)创建一个”aaa“对象,然后将堆中的这个”aaa“对象的地址返回来,赋给 s 引用, 导致 s 指向了堆中所创建的这个”aaa“对象。', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7892, '', 'Java SE Lesson 4', '2019-11-28 22:26:44', '2019-11-29 05:42:22', '1.包装类(Wrapper Class)。针对于原生数据类型的包装。所有的包装类(8 个)都位于 java.lang 包下。Java 中的 8 个包装类分别是:Byte, Short, Integer, Long, Float, Double, Character, Boolean。他们的使用方式都是一样的,可以实现原生数据类型与包装类型的双向转换。\r\n\r\n2.数组(Array):相同类型数据的集合就叫做数组。\r\n\r\n3.如何定义数组。type[] 变量名 = new type[数组中元素的个数];可以按照下列方式定义长度为 10 的数组: \r\nint[] a = new int[10]; 或者 int a[] = new int[10];\r\n\r\n4.数组中的元素索引是从 0 开始的。对于数组来说,最大的索引==数组的长度 – 1。\r\n\r\n5.定义数组的第 3 种方式: type[] 变量名 = {new type[]}{逗号分隔的初始化值列表};\r\n\r\n6.Java 中的每个数组都有一个名为 length 的属性,表示数组的长度。length 属性是 public, final,int 的。数组长度一旦确定,就不能改变大小。\r\n\r\n7. int[] a = new int[10],其中 a 是一个引用,它指向了生成的数组对象的首地址,数组中每个元素都是 int 类型,其中仅存放数据值本身。\r\n\r\n8.二维数组。二维数组是一种平面的二维结构,本质上是数组的数组。二维数组的定义方式:type[][] a = new type[2][3];\r\n\r\n9.三维数组。type[][][] a = new type[2][3][4];\r\n\r\n10.冒泡排序。(掌握交换排序,快速排序的原理与实现方式)\r\n\r\n11.二分查找(Binary Search):待查找的数组要有序。\r\n\r\n12.随机生成 50 个数字(整数),每个数字的范围是[10, 50],统计每个数字出现的次数以及出现次数最多的数字与它的个数,最后将每个数字及其出现次数打印出来,如果某个数字出现次数为 0,则不要打印它。打印时按照数字的升序排列。', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7894, '', '', '2020-12-17 14:48:33', '2020-12-17 14:48:33', 'h2数据库字段设置为null的方法:ALTER TABLE bg_posts ALTER COLUMN post_title set null;', 1, 0, NULL, NULL, 'publish', 'essay', 1, 0); +INSERT INTO `posts` VALUES (7925, '', '', '2020-12-18 13:37:49', '2020-12-18 13:37:50', 'kpl明天总决赛啊,期待。。。', 1, 0, NULL, NULL, 'publish', 'essay', 1, 0); +INSERT INTO `posts` VALUES (7926, '', '', '2020-12-21 16:10:37', '2020-12-21 16:10:37', 'DYG夺冠了', 1, 0, NULL, NULL, 'publish', 'essay', 1, 0); +INSERT INTO `posts` VALUES (7927, '', '', '2020-12-28 10:21:46', '2020-12-28 10:21:46', '为什么周一早上头都很晕。。。', 1, 0, NULL, NULL, 'publish', 'essay', 1, 0); +INSERT INTO `posts` VALUES (7928, '', '', '2021-01-21 17:08:17', '2021-01-21 17:08:17', '期待东冠DYG与南京决战。。。', 1, 0, NULL, NULL, 'publish', 'essay', 1, 0); +INSERT INTO `posts` VALUES (7929, '', '', '2021-04-06 11:05:05', '2021-04-06 11:05:05', '遇到个很难解决的服务单', 1, 0, NULL, NULL, 'publish', 'essay', 1, 0); +INSERT INTO `posts` VALUES (7930, '', '', '2021-06-04 16:57:09', '2021-06-04 16:57:10', '设计即产品提测', 1, 0, NULL, NULL, 'publish', 'essay', 1, 0); +INSERT INTO `posts` VALUES (7931, '', '', '2021-07-07 10:41:02', '2021-07-07 10:41:03', '世冠杯2021又开始了,这赛季ttg不太行', 1, 0, NULL, NULL, 'publish', 'essay', 1, 0); +INSERT INTO `posts` VALUES (7932, '', '', '2021-09-29 15:41:17', '2021-09-29 15:41:17', '有人聊天嘛\n', 1, 0, NULL, NULL, 'publish', 'essay', 1, 0); +INSERT INTO `posts` VALUES (7933, '', '', '2021-11-15 21:59:06', '2021-11-15 21:59:07', '开始学习了', 1, 0, NULL, NULL, 'publish', 'essay', 1, 0); +INSERT INTO `posts` VALUES (7934, '', '', '2021-12-09 19:45:40', '2021-12-10 03:45:40', '时隔三年,重新部署回归博客。', 1, 0, NULL, NULL, 'publish', 'essay', 1, 0); +INSERT INTO `posts` VALUES (7935, '', '', '2021-12-10 04:32:45', '2021-12-10 12:32:45', '中午有点困', 1, 0, NULL, NULL, 'publish', 'essay', 1, 0); +INSERT INTO `posts` VALUES (7936, '', '【Java高级工程师蜕变之路】001 JDBC的问题分析', '2021-12-11 02:25:46', '2021-12-11 02:26:26', '# 核心实现\n\n```\npackage test;\n\nimport java.sql.Connection;\nimport java.sql.DriverManager;\nimport java.sql.PreparedStatement;\nimport java.sql.ResultSet;\n\n/**\n * @author terwer\n * @Description\n * @create 2021-11-30 23:18\n */\npublic class Main {\n public static void main(String[] args) {\n Connection connection = null;\n PreparedStatement preparedStatement = null;\n ResultSet resultSet = null;\n try {\n // 1、加载数据库驱动\n Class.forName(\"com.mysql.jdbc.Driver\");\n // 2、获取数据库链接\n connection = DriverManager.getConnection(\"jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8&useSSL=false\", \"root\", \"123456\");\n\n // 3、定义sql语句\n String sql = \"select * from user where username = ?\";\n // 4、获取预处理对象\n preparedStatement = connection.prepareStatement(sql);\n // 5、设置参数\n preparedStatement.setString(1, \"hp\");\n // 6、拿到查询的数据库结果\n resultSet = preparedStatement.executeQuery();\n\n while (resultSet.next()) {\n int id = resultSet.getInt(\"id\");\n String username = resultSet.getString(\"username\");\n\n User user = new User();\n user.setId(id);\n user.setUsername(username);\n\n System.out.println(\"user = \" + user.toString());\n }\n\n // JDBC问题分析\n // 1、数据库链接信息等存在硬编码 解决:配置文件\n // 2、频繁创建释放数据库链接 解决:连接池(c3p0、druid)\n\n // 查询过程问题分析\n // 1、sql语句、参数、结果集存在硬编码 解决:配置文件\n\n // 结果集问题分析\n // 1、需要手动封装结果集 解决:反射进行对象映射、内省\n\n } catch (Exception e) {\n e.printStackTrace();\n } finally {\n System.out.println(\"释放资源\");\n }\n }\n}\n\n```\n\n1.1 问题分析\nJDBC问题总结:\n原始jdbc开发存在的问题如下:\n1、 数据库连接创建、释放频繁造成系统资源浪费,从而影响系统性能。\n2、 Sql语句在代码中硬编码,造成代码不易维护,实际应用中sql变化的可能较大,sql变动需要改变 java代码。\n3、 使用preparedStatement向占有位符号传参数存在硬编码,因为sql语句的where条件不一定,可能 多也可能少,修改sql还要修改代码,系统不易维护。\n4、 对结果集解析存在硬编码(查询列名),sql变化导致解析代码变化,系统不易维护,如果能将数据库记录封装成 pojo对象解析比较方便\n\n1.2 问题解决思路\n1使用数据库连接池初始化连接资源\n2将sql语句抽取到xml配置文件中\n3使用反射、内省等底层技术,自动将实体与表进行属性与字段的自动映射\n\n\n# mysql驱动链接 \n\nhttps://files.cnblogs.com/files/tangyouwei/mysql-connector-java-5.1.49.jar.zip\n\n# 源码\n\nhttps://github.com/terwer/mybatis-test', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7937, '', '', '2021-12-18 08:13:37', '2021-12-18 16:13:37', '开始学习Spring MVC', 1, 0, NULL, NULL, 'publish', 'essay', 1, 0); +INSERT INTO `posts` VALUES (7938, '', '', '2021-12-22 06:30:01', '2021-12-22 14:30:01', '发现一个很不错的接口测试工具:apipost。全中文的', 1, 0, NULL, NULL, 'publish', 'essay', 1, 0); +INSERT INTO `posts` VALUES (7939, 'java-lei-jia-zai-qi-shen-ru-pou-xi', 'Java类加载器深入剖析', '2022-01-15 23:56:23', '2022-01-15 23:58:21', '1、 ClassLoader(类加载器)\n\n## Java程序的生命周期\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220115230535768-1239712586.jpg&w=500&h=500)\n\n## 类的加载、连接与初始化\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220115230535780-1084186116.jpg&w=500&h=500)\n \n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220115230535496-500161437.jpg&w=500&h=500)\n\n## Java对类的使用方式\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220115230535652-302283572.jpg&w=500&h=500)\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220115230535805-145295574.jpg&w=500&h=500)\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220115230535591-1758286776.jpg&w=500&h=500)\n\n## 类的加载\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220115230535683-2060616735.jpg&w=500&h=500)\n\n## 加载类的方式\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220115230535680-1980218234.jpg&w=500&h=500)\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220115230535612-645989888.jpg&w=500&h=500)\n\n# 我的博客园\n\nhttps://www.cnblogs.com/tangyouwei/p/java-lei-jia-zai-qi-shen-ru-pou-xi.html \n\n # PS:有用的小技巧\n\n解决防盗链问题。默认cnblogs图片引用会出现403\n\nhttps://stevenocean.github.io/2021/01/29/minio-image-serve.html \n\n图片参数看这里\n\nhttps://images.weserv.nl/docs/quick-reference.html', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7940, 'tomcat-gao-ji-shi-yong-ji-yuan-li', 'Tomcat高级使用及原理', '2022-01-18 15:35:08', '2022-01-18 15:34:59', '# 什么是bs模式\n\nbrowser/server:浏览器、服务器\n\n浏览器客户端发起http请求到服务器,服务器返回结果给浏览器,浏览器展示返回的内容\n\n# 浏览器访问服务器的流程\n\nhttp请求处理过程\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118152521227-648895264.jpg&w=500&h=500)\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118152522083-634572866.jpg&w=500&h=500)\n\n浏览器访问服务器使用的http协议,http是应用层协议,定义了数据通信的格式\n\n具体的传输由传输层控制,使用的是TCP/IP协议\n\n# Tomcat的系统架构\n\ntomcat是一个http服务器,能够接收并处理http请求\n\n## Tomcat请求处理流程\n\n浏览器发起请求->远端服务器接收请求,调用java类处理对应的请求\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118152521647-2029054303.jpg&w=500&h=500)\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118152521123-379796969.jpg&w=500&h=500)\n\nhttp请求到达服务器之后,会交给Servlet容器来处理,Servlet通过Sevlet接口调用业务类。\n\nServlet容器和Servlet接口的整套内容叫做Servlet规范\n\n最新的Servlet规范是Servlet5.0\n\nhttps://jakarta.ee/specifications/servlet/5.0/jakarta-servlet-spec-5.0.html\n\nTomcat按照Servlet规范实现了Servlet容器,兼备Servlet和http的功能\n\nTomcat的双重身份\n\n1、http服务器\n\n2、Servlet容器\n\n## Tomcat Servlet容器处理流程\n\n请求通过某个特定的URL到达服务器\n\n1、http服务器把请求封装成SevletRequest对象\n\n2、调用Servlet容器中的某个Sevlet\n\n3、在上一步骤中,Servlet容器通过URL与Sevlet的映射关系,找到对应的Servlet\n\n4、如果Servlet没有加载,就使用反射创建Servlet,并调用init方法初始化这个Servlet\n\n5、调用Servlet的service方法处理请求,并将结果封装成ServletResponse对象\n\n6、ServletResponse对象返回给浏览器,浏览器渲染页面\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118152521122-1519242977.jpg&w=500&h=500)\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118152521508-1045179621.jpg&w=500&h=500)\n\n## Tomcat总体系统架构\n\nTomcat的两个重要功能\n\n1、和客户端浏览器交互,通过socket通信,将字节流与ServletRequest和ServletResponse进行转换\n\n2、Servlet容器处理业务逻辑\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118152521781-870979704.jpg&w=500&h=500)\n\nTomcat的2大角色对应了两个核心组件\n\n连接器(Connector)和容器(Container)\n\n连接器:对外交流,socket链接,处理字节流与Request和Response的转换\n\n容器:对内管理,加载和管理Servlet,处理Request请求\n\n# Tomcat的连接器组件 Coyote\n\n## Coyote简介\n\n客户端通过 Coyote 与服务器建立链接,发送请求并接收响应\n\n1、Coyote 封装了底层网络通信 (接收请求与响应处理)\n\n2、Coyote 使得 Catania 容器与具体的协议和I/O操作方式解耦\n\n3、Coyote将Socket输入转换封装成Request对象,进一步封装之后交给 Catania 容器处理,处理完成之后,Catania通过Coyote将Response对象的结果写入到输出流\n\n4、Coyote 负责的是具体协议(应用层)和I/O(传输层)\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118152521124-1087680436.jpg&w=500&h=500)\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118152521126-1230998085.jpg&w=500&h=500)\n\nCoyote 支持的IO模型与协议\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118152522176-1955038400.jpg&w=500&h=500)\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118152521973-1061223124.jpg&w=500&h=500)\n\n8.0之前Tomcat的默认IO方式为BIO,8.0之后为NIO,性能要优于BIO,APR是本地库,性能最佳,但是需要操作系统底层支持,要安装可移植库\n\n## Coyote的内部组件\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118152519151-2036946306.jpg&w=500&h=500)\n\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118152523247-534835350.png)\n\nCoyote 组件的作用\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118152523743-2025601584.jpg&w=500&h=500)\n\n# Tomcat的Servlet容器 Catania\n\n## Tomcat的分层结构以及Catania的位置\n\nTomcat是有一系列配置 conf/server.xml 构成的Web容器,而Catania 则是Servlet容器。\n\nTomcat的本质是Servlet容器,Catania是啥Tomcat的核心,其他组件都是为Catania服务的。\nJasper是处理jsp的,naming提供JNDI,juli提供日志服务。\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118152521140-402477633.jpg&w=500&h=500)\n\n## Servlet容器Catania的结构\n\nTomcat/Catalina实例\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118152522172-1588939203.jpg&w=500&h=500)\n\n一个Catalina实例(容器)\n\n一个 Server实例(容器)\n\n多个Service实例(容器)\n\n每一个Service实例下可以有多个Connector实例和一个Container实例\n\nCatalina \n负责解析Tomcat的配置文件(server.xml) , 以此来创建服务器Server组件并进行管理\n\nServer \n服务器表示整个Catalina Servlet容器以及其它组件,负责组装并启动Servlaet引擎,Tomcat连接器。Server通过实现Lifecycle接口,提供了一种优雅的启动和关闭整个系统的方式\n\nService \n服务是Server内部的组件,一个Server包含多个Service。它将若干个Connector组件绑定到一个 Container\n\nContainer容器,负责处理用户的servlet请求,并返回对象给web用户的模块\n\n## Container组件的具体结构\n\nEngine \n表示整个Catalina的Servlet引擎,用来管理多个虚拟站点,一个Service最多只能有一个Engine, 但是一个引擎可包含多个Host\n\nHost \n代表一个虚拟主机,或者说一个站点,可以给Tomcat配置多个虚拟主机地址,而一个虚拟主机下\n可包含多个Context\n\nContext \n表示一个Web应用程序, 一个Web应用可包含多个Wrapper \n\nWrapper \n表示一个Servlet,Wrapper 作为容器中的最底层,不能包含子容器 \n\n上述组件的配置其体现在 `conf/server.xml` 中\n\n# Tomcat的核心配置\n\nTomcat 作为服务器的配置,主要是 server.xml 文件的配置; \n\nserver.xml中包含了 Servlet容器的相关配置,即 Catalina 的配置;\n\n## server.xml 的主要结构\n\n```\n\n\n \n \n \n \n \n \n \n \n\n```\n\n### Server 标签\n\n```\n\n\n\n \n\n\n\n \n \n \n\n\n \n \n \n \n \n \n ...\n \n\n```\n\n### Service标签\n\n```\n \n\n\n ...\n\n```\n\n### Executor标签\n\n```\n\n\n```\n\n### Connector 标签\n\n用于创建连接器实例\n\n默认配置了两个连接器,一个支持http,一个支持AJP\n\n```\n \n\n \n\n```\n\n使用共享线程池\n\n```\n\n```\n\n### Engine标签\n\nEngine表示Sevlet引擎\n\n```\n\n\n...\n\n```\n\n### Host标签\n\n用于配置虚拟主机\n\n```\n\n ...\n\n```\n### Context标签\n\nContext标签表示一个具体的Web应用\n\n```\n\n\n \n```', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7941, 'tomcat-yuan-ma-pou-xi-yu-diao-you', 'Tomcat源码剖析与调优', '2022-01-18 20:24:57', '2022-01-18 20:25:44', '# 手写mini版Tomcat\n\nMinicat要做的事情:\n\n作为一个服务器软件提供服务的,也即我们可以通过浏览器客户端发送http请求, Minicat可以接收到请求进行处理,处理之后的结果可以返回浏览器客户端。\n1)提供服务,接收请求(Socket通信) 2)请求信息封装成Request对象(Response对象) 3)客户端请求资源,资源分为静态资源(html)和动态资源(Servlet) 4)资源返回给客户端浏览器\n\n## 1.0\nV1.0需求:浏览器请求http://localhost:8080 ,返回一个固定的字符串到⻚面\"Hello Minicat!\" \n\n## 2.0\nV2.0需求:封装Request和Response对象,返回html静态资源文件 \n\n## 3.0\nV3.0需求:可以请求动态资源(Servlet)\n\n## 4.0\nV4.0需求:在已有Minicat基础上进一步扩展,模拟出webapps部署效果 磁盘上放置一个webapps目录,webapps中可以有多个项目,例如demo1、demo2、demo3... 每个项目中含有servlet,可以根据请求url定位对应servlet进一步处理。\n\n## 最终代码\n完成4.0版本之后,最终代码如下:\n\n### Bootstrap启动类\n\n```\n/**\n * Minicat的主类\n */\npublic class Bootstrap {\n\n /**\n * 定义socket监听的端口号\n */\n private int port = 8080;\n\n public int getPort() {\n return port;\n }\n\n public void setPort(int port) {\n this.port = port;\n }\n\n\n /**\n * Minicat启动需要初始化展开的一些操作\n */\n public void start() throws Exception {\n\n // 加载解析相关的配置,web.xml\n loadServlet();\n\n // 解析server.xml,读取webapps路径\n // 遍历webapps,每个应用通过单独设置类加载器(防止默认的类加载机制导致不同应用的相同class问题)\n // 读取web.xml的servlet配置,生成servlet保存到servletMap\n // 保存的key需要加上应用的前缀\n loadWebapps();\n\n System.out.println(\"全部加载完成,servletMap:\" + servletMap);\n\n // 定义一个线程池\n int corePoolSize = 10;\n int maximumPoolSize = 50;\n long keepAliveTime = 100L;\n TimeUnit unit = TimeUnit.SECONDS;\n BlockingQueue workQueue = new ArrayBlockingQueue<>(50);\n ThreadFactory threadFactory = Executors.defaultThreadFactory();\n RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();\n\n\n ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(\n corePoolSize,\n maximumPoolSize,\n keepAliveTime,\n unit,\n workQueue,\n threadFactory,\n handler\n );\n\n\n /*\n 完成Minicat 1.0版本\n 需求:浏览器请求http://localhost:8080,返回一个固定的字符串到页面\"Hello Minicat!\"\n */\n ServerSocket serverSocket = new ServerSocket(port);\n System.out.println(\"=====>>>Minicat start on port:\" + port);\n\n /*while(true) {\n Socket socket = serverSocket.accept();\n // 有了socket,接收到请求,获取输出流\n OutputStream outputStream = socket.getOutputStream();\n String data = \"Hello Minicat!\";\n String responseText = HttpProtocolUtil.getHttpHeader200(data.getBytes().length) + data;\n outputStream.write(responseText.getBytes());\n socket.close();\n }*/\n\n\n /**\n * 完成Minicat 2.0版本\n * 需求:封装Request和Response对象,返回html静态资源文件\n */\n /*while(true) {\n Socket socket = serverSocket.accept();\n InputStream inputStream = socket.getInputStream();\n\n // 封装Request对象和Response对象\n Request request = new Request(inputStream);\n Response response = new Response(socket.getOutputStream());\n\n response.outputHtml(request.getUrl());\n socket.close();\n\n }*/\n\n\n /**\n * 完成Minicat 3.0版本\n * 需求:可以请求动态资源(Servlet)\n */\n /*while(true) {\n Socket socket = serverSocket.accept();\n InputStream inputStream = socket.getInputStream();\n\n // 封装Request对象和Response对象\n Request request = new Request(inputStream);\n Response response = new Response(socket.getOutputStream());\n\n // 静态资源处理\n if(servletMap.get(request.getUrl()) == null) {\n response.outputHtml(request.getUrl());\n }else{\n // 动态资源servlet请求\n HttpServlet httpServlet = servletMap.get(request.getUrl());\n httpServlet.service(request,response);\n }\n\n socket.close();\n\n }\n*/\n\n /*\n 多线程改造(不使用线程池)\n */\n /*while(true) {\n Socket socket = serverSocket.accept();\n RequestProcessor requestProcessor = new RequestProcessor(socket,servletMap);\n requestProcessor.start();\n }*/\n // System.out.println(\"=========>>>>>>使用线程池进行多线程改造\");\n /*\n 多线程改造(使用线程池)\n */\n /*\n while(true) {\n\n Socket socket = serverSocket.accept();\n RequestProcessor requestProcessor = new RequestProcessor(socket,servletMap);\n //requestProcessor.start();\n threadPoolExecutor.execute(requestProcessor);\n }\n */\n\n /**\n * 完成Minicat 4.0版本\n * 需求:实现webapps部署,并支持多项目部署\n */\n while (true) {\n Socket socket = serverSocket.accept();\n RequestProcessor requestProcessor = new RequestProcessor(socket, servletMap);\n threadPoolExecutor.execute(requestProcessor);\n }\n }\n\n /**\n * 加载解析server.xml,初始化webapps里面的servlet\n */\n private void loadWebapps() {\n InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream(\"server.xml\");\n SAXReader saxReader = new SAXReader();\n\n try {\n Document document = saxReader.read(resourceAsStream);\n Element element = document.getRootElement();\n\n // 为了简单,暂不考虑多个host的情况,以单个host为例\n List hosts = element.selectNodes(\"//Host\");\n // 未找到主机,不处理\n if (null == hosts || hosts.size() == 0) {\n return;\n }\n\n Element host = hosts.get(0);\n String appBase = host.attributeValue(\"appBase\");\n\n // 找到appBase\n String classPath = this.getClass().getResource(\".\").getFile();\n String absoluteAppBase = Paths.get(classPath).getParent().getParent().getParent().toAbsolutePath().toString() + \"/\" + appBase;\n File file = new File(absoluteAppBase);\n if (!file.exists()) {\n System.out.println(\"webapps目录不存在,将不会加载任何应用\");\n return;\n }\n System.out.println(\"准备从下面的目录加载webapps:\" + absoluteAppBase + \"\\n\");\n\n File[] dirs = file.listFiles();\n\n for (File dir : dirs) {\n if (!dir.isDirectory()) {\n continue;\n }\n\n // 遍历每个应用\n String appPath = \"/\" + dir.getName();\n\n List contextList = host.elements();\n for (Element context : contextList) {\n String docBase = context.attributeValue(\"docBase\");\n if (!appPath.equals(docBase)) {\n continue;\n }\n\n String appPrefix = context.attributeValue(\"path\");\n String absAppPath = absoluteAppBase + docBase;\n\n System.out.println(\"开始加载应用:\" + appPrefix + \",应用路径:\" + absAppPath);\n // 加载各个应用的servlet\n loadWebappsServlet(appPrefix, absAppPath);\n }\n }\n System.out.println(\"加载webapps的servlet完成\");\n } catch (DocumentException e) {\n e.printStackTrace();\n }\n }\n\n\n private Map servletMap = new HashMap();\n\n /**\n * 加载解析web.xml,初始化Servlet\n */\n private void loadServlet() {\n InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream(\"web.xml\");\n SAXReader saxReader = new SAXReader();\n\n try {\n Document document = saxReader.read(resourceAsStream);\n Element rootElement = document.getRootElement();\n\n List selectNodes = rootElement.selectNodes(\"//servlet\");\n for (int i = 0; i < selectNodes.size(); i++) {\n Element element = selectNodes.get(i);\n // lagou\n Element servletnameElement = (Element) element.selectSingleNode(\"servlet-name\");\n String servletName = servletnameElement.getStringValue();\n // server.LagouServlet\n Element servletclassElement = (Element) element.selectSingleNode(\"servlet-class\");\n String servletClass = servletclassElement.getStringValue();\n\n\n // 根据servlet-name的值找到url-pattern\n Element servletMapping = (Element) rootElement.selectSingleNode(\"/web-app/servlet-mapping[servlet-name=\'\" + servletName + \"\']\");\n // /lagou\n String urlPattern = servletMapping.selectSingleNode(\"url-pattern\").getStringValue();\n servletMap.put(urlPattern, (HttpServlet) Class.forName(servletClass).newInstance());\n\n }\n\n System.out.println(\"加载servlet完成\");\n } catch (DocumentException e) {\n e.printStackTrace();\n } catch (IllegalAccessException e) {\n e.printStackTrace();\n } catch (InstantiationException e) {\n e.printStackTrace();\n } catch (ClassNotFoundException e) {\n e.printStackTrace();\n }\n\n }\n\n private void loadWebappsServlet(String appPrefix, String absAppPath) {\n InputStream resourceAsStream = null;\n try {\n resourceAsStream = new FileInputStream(absAppPath + \"/web.xml\");\n\n SAXReader saxReader = new SAXReader();\n\n Document document = saxReader.read(resourceAsStream);\n Element rootElement = document.getRootElement();\n\n List selectNodes = rootElement.selectNodes(\"//servlet\");\n for (int i = 0; i < selectNodes.size(); i++) {\n Element element = selectNodes.get(i);\n // lagou\n Element servletnameElement = (Element) element.selectSingleNode(\"servlet-name\");\n String servletName = servletnameElement.getStringValue();\n // server.LagouServlet\n Element servletclassElement = (Element) element.selectSingleNode(\"servlet-class\");\n String servletClass = servletclassElement.getStringValue();\n\n\n // 根据servlet-name的值找到url-pattern\n Element servletMapping = (Element) rootElement.selectSingleNode(\"/web-app/servlet-mapping[servlet-name=\'\" + servletName + \"\']\");\n // /lagou\n String urlPattern = servletMapping.selectSingleNode(\"url-pattern\").getStringValue();\n\n // 使用自定义的类加载器加载\n MyClassLoader loader = new MyClassLoader(absAppPath, servletClass);\n Class aClass = loader.loadClass(servletClass);\n\n // 注意:下面的会从默认的类加载器加载\n // Class aClass = Class.forName(servletClass);\n\n // 加载失败不添加\n if (null == aClass) {\n continue;\n }\n\n servletMap.put(appPrefix + urlPattern, (HttpServlet) aClass.newInstance());\n\n }\n\n System.out.println(\"加载应用\" + appPrefix + \"的servlet完成\\n\");\n } catch (DocumentException e) {\n e.printStackTrace();\n } catch (IllegalAccessException e) {\n e.printStackTrace();\n } catch (InstantiationException e) {\n e.printStackTrace();\n } catch (ClassNotFoundException e) {\n e.printStackTrace();\n } catch (FileNotFoundException e) {\n e.printStackTrace();\n }\n }\n\n\n /**\n * Minicat 的程序启动入口\n *\n * @param args\n */\n public static void main(String[] args) {\n Bootstrap bootstrap = new Bootstrap();\n try {\n // 启动Minicat\n bootstrap.start();\n } catch (IOException e) {\n e.printStackTrace();\n } catch (Exception e) {\n e.printStackTrace();\n }\n }\n}\n```\n\n### 自定义的ClassLoader\n\n```\n/**\n * 自定义类加载器,主要用于应用的servlet加载\n *\n * @name: MyClassLoader\n * @author: terwer\n * @date: 2022-01-18 10:19\n **/\npublic class MyClassLoader extends ClassLoader {\n\n private String absAppPath;\n private String servletClass;\n\n public MyClassLoader(String absAppPath, String servletClass) {\n this.absAppPath = absAppPath;\n this.servletClass = servletClass;\n }\n\n /**\n * 通过指定全路径记载class文件\n *\n * @param name class文件路径(包名+class文件名)\n * @return Class\n * @throws ClassNotFoundException\n */\n @Override\n public Class loadClass(String name) throws ClassNotFoundException {\n // 这里要注意:如果不是servlet,需要使用双亲委派\n // 因为应用里面会使用Minicat里面定义的类\n // 而这些类没必要拷贝一份到应用里面\n // 只有servlet才去跳过双亲委派\n if (!name.equals(this.servletClass)) {\n System.out.println(\"非servlet,不使用自定义类加载器:\" + name);\n Class clazz = this.getClass().getClassLoader().loadClass(name);\n return clazz;\n }\n\n String filePath = absAppPath + \"/\" + name.replaceAll(\"\\\\.\", \"/\") + \".class\";\n String classFullPath = \"file://\" + filePath;\n System.out.println(\"MyClassLoader开始加载:\" + classFullPath);\n\n byte[] classBytes = null;\n Path path = null;\n\n try {\n path = Paths.get(new URI(classFullPath));\n classBytes = Files.readAllBytes(path);\n } catch (URISyntaxException | IOException e) {\n e.printStackTrace();\n }\n\n Class clazz = defineClass(name, classBytes, 0, classBytes.length);\n\n return clazz;\n }\n}\n```\n\n### http协议工具类\n\n```\n/**\n * http协议工具类,主要是提供响应头信息,这里我们只提供200和404的情况\n */\npublic class HttpProtocolUtil {\n\n /**\n * 为响应码200提供请求头信息\n * @return\n */\n public static String getHttpHeader200(long contentLength) {\n return \"HTTP/1.1 200 OK \\n\" +\n \"Content-Type: text/html \\n\" +\n \"Content-Length: \" + contentLength + \" \\n\" +\n \"\\r\\n\";\n }\n\n /**\n * 为响应码404提供请求头信息(此处也包含了数据内容)\n * @return\n */\n public static String getHttpHeader404() {\n String str404 = \"

    404 not found

    \";\n return \"HTTP/1.1 404 NOT Found \\n\" +\n \"Content-Type: text/html \\n\" +\n \"Content-Length: \" + str404.getBytes().length + \" \\n\" +\n \"\\r\\n\" + str404;\n }\n}\n```\n\n### Request封装类\n\n```\n/**\n * 把请求信息封装为Request对象(根据InputSteam输入流封装)\n */\npublic class Request {\n\n private String method; // 请求方式,比如GET/POST\n private String url; // 例如 /,/index.html\n\n private InputStream inputStream; // 输入流,其他属性从输入流中解析出来\n\n\n public String getMethod() {\n return method;\n }\n\n public void setMethod(String method) {\n this.method = method;\n }\n\n public String getUrl() {\n return url;\n }\n\n public void setUrl(String url) {\n this.url = url;\n }\n\n public InputStream getInputStream() {\n return inputStream;\n }\n\n public void setInputStream(InputStream inputStream) {\n this.inputStream = inputStream;\n }\n\n public Request() {\n }\n\n\n // 构造器,输入流传入\n public Request(InputStream inputStream) throws IOException {\n this.inputStream = inputStream;\n\n // 从输入流中获取请求信息\n int count = 0;\n while (count == 0) {\n count = inputStream.available();\n }\n\n byte[] bytes = new byte[count];\n inputStream.read(bytes);\n\n String inputStr = new String(bytes);\n // 获取第一行请求头信息\n String firstLineStr = inputStr.split(\"\\\\n\")[0]; // GET / HTTP/1.1\n\n String[] strings = firstLineStr.split(\" \");\n\n this.method = strings[0];\n this.url = strings[1];\n\n System.out.println(\"=====>>method:\" + method);\n System.out.println(\"=====>>url:\" + url);\n\n\n }\n}\n```\n\n### Response封装类\n\n```\n/**\n * 封装Response对象,需要依赖于OutputStream\n *\n * 该对象需要提供核心方法,输出html\n */\npublic class Response {\n\n private OutputStream outputStream;\n\n public Response() {\n }\n\n public Response(OutputStream outputStream) {\n this.outputStream = outputStream;\n }\n\n\n // 使用输出流输出指定字符串\n public void output(String content) throws IOException {\n outputStream.write(content.getBytes());\n }\n\n\n /**\n *\n * @param path url,随后要根据url来获取到静态资源的绝对路径,进一步根据绝对路径读取该静态资源文件,最终通过\n * 输出流输出\n * /-----> classes\n */\n public void outputHtml(String path) throws IOException {\n // 获取静态资源文件的绝对路径\n String absoluteResourcePath = StaticResourceUtil.getAbsolutePath(path);\n\n // 输入静态资源文件\n File file = new File(absoluteResourcePath);\n if(file.exists() && file.isFile()) {\n // 读取静态资源文件,输出静态资源\n StaticResourceUtil.outputStaticResource(new FileInputStream(file),outputStream);\n }else{\n // 输出404\n output(HttpProtocolUtil.getHttpHeader404());\n }\n\n }\n\n}\n```\n\n### 静态资源处理工具类\n\n```\npublic class StaticResourceUtil {\n\n /**\n * 获取静态资源文件的绝对路径\n * @param path\n * @return\n */\n public static String getAbsolutePath(String path) {\n String absolutePath = StaticResourceUtil.class.getResource(\"/\").getPath();\n return absolutePath.replaceAll(\"\\\\\\\\\",\"/\") + path;\n }\n\n\n /**\n * 读取静态资源文件输入流,通过输出流输出\n */\n public static void outputStaticResource(InputStream inputStream, OutputStream outputStream) throws IOException {\n\n int count = 0;\n while(count == 0) {\n count = inputStream.available();\n }\n\n int resourceSize = count;\n // 输出http请求头,然后再输出具体内容\n outputStream.write(HttpProtocolUtil.getHttpHeader200(resourceSize).getBytes());\n\n // 读取内容输出\n long written = 0 ;// 已经读取的内容长度\n int byteSize = 1024; // 计划每次缓冲的长度\n byte[] bytes = new byte[byteSize];\n\n while(written < resourceSize) {\n if(written + byteSize > resourceSize) { // 说明剩余未读取大小不足一个1024长度,那就按真实长度处理\n byteSize = (int) (resourceSize - written); // 剩余的文件内容长度\n bytes = new byte[byteSize];\n }\n\n inputStream.read(bytes);\n outputStream.write(bytes);\n\n outputStream.flush();\n written+=byteSize;\n }\n }\n}\n```\n### 动态资源请求\n\n#### Servlet\n\n```\npublic interface Servlet {\n\n void init() throws Exception;\n\n void destory() throws Exception;\n\n void service(Request request,Response response) throws Exception;\n}\n\n```\n\n#### HttpServlet\n\n```\npublic abstract class HttpServlet implements Servlet{\n\n\n public abstract void doGet(Request request,Response response);\n\n public abstract void doPost(Request request,Response response);\n\n\n @Override\n public void service(Request request, Response response) throws Exception {\n if(\"GET\".equalsIgnoreCase(request.getMethod())) {\n doGet(request,response);\n }else{\n doPost(request,response);\n }\n }\n}\n```\n\n#### 业务类LagouServlet\n\n```\npublic class LagouServlet extends HttpServlet {\n @Override\n public void doGet(Request request, Response response) {\n\n\n // try {\n // Thread.sleep(100000);\n // } catch (InterruptedException e) {\n // e.printStackTrace();\n // }\n String content = \"

    LagouServlet get

    \";\n try {\n response.output((HttpProtocolUtil.getHttpHeader200(content.getBytes().length) + content));\n } catch (IOException e) {\n e.printStackTrace();\n }\n }\n\n @Override\n public void doPost(Request request, Response response) {\n String content = \"

    LagouServlet post

    \";\n try {\n response.output((HttpProtocolUtil.getHttpHeader200(content.getBytes().length) + content));\n } catch (IOException e) {\n e.printStackTrace();\n }\n }\n\n @Override\n public void init() throws Exception {\n\n }\n\n @Override\n public void destory() throws Exception {\n\n }\n}\n```\n\n#### 多线程版RequestProcessor\n\n```\npublic class RequestProcessor extends Thread {\n\n private Socket socket;\n private Map servletMap;\n\n public RequestProcessor(Socket socket, Map servletMap) {\n this.socket = socket;\n this.servletMap = servletMap;\n }\n\n @Override\n public void run() {\n try{\n InputStream inputStream = socket.getInputStream();\n\n // 封装Request对象和Response对象\n Request request = new Request(inputStream);\n Response response = new Response(socket.getOutputStream());\n\n // 静态资源处理\n if(servletMap.get(request.getUrl()) == null) {\n response.outputHtml(request.getUrl());\n }else{\n // 动态资源servlet请求\n HttpServlet httpServlet = servletMap.get(request.getUrl());\n httpServlet.service(request,response);\n }\n\n socket.close();\n\n }catch (Exception e) {\n e.printStackTrace();\n }\n\n }\n}\n```\n\n### 完整代码地址\n\nhttps://gitee.com/youweics/Minicat\n\n# Tomcat源码剖析\n\n## Tomcat源码构建\n\n下载源码 \n\nhttps://tomcat.apache.org/download-80.cgi\n\nhttps://dlcdn.apache.org/tomcat/tomcat-8/v8.5.73/src/apache-tomcat-8.5.73-src.tar.gz\n\n## 源码导入准备\n\n1. 解压源码,在 apache-tomcat-8.5.73-src 目录创建一个 pom.xml 文件,内容如下\n\n```\n\n\n \n org.apache.maven.plugins\n maven-compiler-plugin\n 3.1\n \n UTF-8\n 11\n 11\n \n \n \n \n \n\n \n org.easymock\n easymock\n 3.4\n \n \n ant\n ant\n1.7.0\n \n \n wsdl4j\n wsdl4j\n 1.6.2\n \n \n javax.xml\n jaxrpc\n 1.1\n \n \n org.eclipse.jdt.core.compiler\n ecj\n 4.5.1\n \n \n javax.xml.soap\n javax.xml.soap-api\n 1.4.0\n \n \n\n```\n\n1. 在 apache-tomcat-8.5.73-src 目录中创建 source 文件夹\n\n2. 将 conf、webapps 目录移动到刚刚创建的 source 文件夹中\n\n## 将源码工程导入到 IDEA 中\n给 tomcat 的源码程序启动类 Bootstrap 配置 VM 参数,因为 tomcat 源码运行也需要加载配置文 件等。\n\n```\n-Dcatalina.home=/Users/terwer/Documents/code/tomcat8/apache-tomcat-8.5.73-src/source\n-Dcatalina.base=/Users/terwer/Documents/code/tomcat8/apache-tomcat-8.5.73-src/source\n-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager\n-Djava.util.logging.config.file=/Users/terwer/Documents/code/tomcat8/apache-tomcat-8.5.73-src/source/conf/logging.properties\n```\n\n解决 JSP 编译错误\n\n需要在tomcat的源码ContextConfig类中 的configureStart方法中增加一行代码将 Jsp 引擎初始化\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118200739503-2083699256.jpg&w=500&h=500)\n\n重启Tomcat。\n\n## Tomcat核心流程源码剖析\n\n### 生命周期\n\nTomcat中的各容器组件都会涉及创建、销毁等,因此设计了生命周期接口Lifecycle进行统一规范,各容 器组件实现该接口。\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118200738140-1192478187.jpg&w=500&h=500)\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118200739499-1614080224.jpg&w=500&h=500)\n\nLifecycle生命周期接口继承体系示意图\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118200738152-2115876949.jpg&w=500&h=500)\n\n### 核心源码\n\n主要关注Tomcat启动流程和Tomcat请求处理流程 \n\n#### Tomcat启动流程\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118200740264-1427327271.jpg&w=500&h=500)\n\n#### Tomcat请求处理流程 \n\n请求处理流程分析\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118200740264-2063317258.jpg&w=500&h=500)\n\n请求处理流程示意图\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118200738312-257029955.jpg&w=500&h=500)\n\nTomcat Mapper组件的体系结构\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118200738100-2041995646.jpg&w=500&h=500)\n\n# Tomcat类加载机制剖析\n\nJava类(.java)—> 字节码文件(.class) —> 字节码文件需要被加载到jvm内存当中(这个过程就是一个 类加载的过程)\n\n类加载器(ClassLoader,说白了也是一个类,jvm启动的时候先把类加载器读取到内存当中去,其他的 类(比如各种jar中的字节码文件,自己开发的代码编译之后的.class文件等等))\n\n要熟悉Tomcat的类加载机制,首先的熟悉JVM的类加载机制,因为Tomcat是运行在JVM之上的\n\n## JVM类加载机制\n\nJVM 的类加载机制中有一个非常重要的⻆色叫做类加载器(ClassLoader),类加载器有自己的体系, Jvm内置了几种类加载器,包括:引导类加载器、扩展类加载器、系统类加载器,他们之间形成父子关 系,通过 Parent 属性来定义这种关系,最终可以形成树形结构。\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118200738179-612325880.jpg&w=500&h=500)\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118200740305-1198696680.jpg&w=500&h=500)\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118200740262-146219585.jpg&w=500&h=500)\n\n\n用户可以自定义类加载器,用于加载特定目录下的class文件\n\n当 JVM 运行过程中,用户自定义了类加载器去加载某些类时,会按照下面的步骤(父类委托机制)\n\n 1) 用户自己的类加载器,把加载请求传给父加载器,父加载器再传给其父加载器,一直到加载器 树的顶层\n \n 2) 最顶层的类加载器首先针对其特定的位置加载,如果加载不到就转交给子类\n \n 3) 如果一直到底层的类加载都没有加载到,那么就会抛出异常 ClassNotFoundException\n \n 因此,按照这个过程可以想到,如果同样在 classpath 指定的目录中和自己工作目录中存放相同的 class,会优先加载 classpath 目录中的文件\n\n## 双亲委派机制\n\n### 什么是双亲委派机制\n\n当某个类加载器需要加载某个.class文件时,它首先把这个任务委托给他的上级类加载器,递归这个操\n作,如果上级的类加载器没有加载,自己才会去加载这个类。\n\n### 双亲委派机制的作用\n\n防止重复加载同一个.class。通过委托去向上面问一问,加载过了,就不用再加载一遍。保证数据\n安全。\n\n保证核心.class不能被篡改。通过委托方式,不会去篡改核心.class,即使篡改也不会去加载,即使 加载也不会是同一个.class对象了。不同的加载器加载同一个.class也不是同一个.class对象。这样保证了class执行安全(如果子类加载器先加载,那么我们可以写一些与java.lang包中基础类同名的类, 然后再定义一个子类加载器,这样整个应用使用的基础类就都变成我们自己定义的类了。 )\nObject类 -----> 自定义类加载器(会出现问题的,那么真正的Object类就可能被篡改了)\n\n## Tomcat的类加载机制\n\nTomcat 的类加载机制相对于 Jvm 的类加载机制做了一些改变。 没有严格的遵从双亲委派机制,也可以说打破了双亲委派机制 \n\n比如:有一个tomcat,webapps下部署了两个应用 \n\napp1/lib/a-1.0.jar com.lagou.edu.Abc\n\napp2/lib/a-2.0.jar com.lagou.edu.Abc \n\n不同版本中Abc类的内容是不同的,代码是不一样的\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118200740824-1642235319.jpg&w=500&h=500)\n\n1. 引导类加载器 和 扩展类加载器 的作用不变\n2. 系统类加载器正常情况下加载的是 CLASSPATH 下的类,但是 Tomcat 的启动脚本并未使用该变 量,而是加载tomcat启动的类,比如bootstrap.jar,通常在catalina.bat或者catalina.sh中指定。 位于CATALINA_HOME/bin下\n3. Common 通用类加载器加载Tomcat使用以及应用通用的一些类,位于CATALINA_HOME/lib下, 比如servlet-api.jar\n4. Catalina ClassLoader 用于加载服务器内部可⻅类,这些类应用程序不能访问 Shared ClassLoader 用于加载应用程序共享类,这些类服务器不会依赖\n5. Webapp ClassLoader,每个应用程序都会有一个独一无二的Webapp ClassLoader,他用来加载 本应用程序 /WEB-INF/classes 和 /WEB-INF/lib 下的类。\n> tomcat 8.5 默认改变了严格的双亲委派机制\n\n> 首先从 Bootstrap Classloader 加载指定的类 如果未加载到,则从 /WEB-INF/classes 加载 如果未加载到,则从 /WEB-INF/lib/*.jar 加载\n\n> 如果未加载到,则依次从 System、Common、Shared 加载(在这最后一步,遵从双亲委派机制)\n\n# Tomcat对https的支持\n\n## https简介\n\nHttp超文本传输协议,明文传输 ,传输不安全,https在传输数据的时候会对数据进行加密 ssl协议\nTLS(transport layer security)协议\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118200740263-1661914781.jpg&w=500&h=500)\n\n### https和http的区别\n\nHTTPS协议使用时需要到电子商务认证授权机构(CA)申请SSL证书 \n\nHTTP默认使用8080端口,HTTPS默认使用8443端口 \n\nHTTPS则是具有SSL加密的安全性传输协议,对数据的传输进行加密,效果上相当于HTTP的升级版 \n\nHTTP的连接是无状态的,不安全的;\n\nHTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比HTTP协议安全\n\n### https的工作原理\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118200740275-285250377.jpg&w=500&h=500)\n\n## Tomcat对https的支持\n\n1、使用 JDK 中的 keytool 工具生成免费的秘钥库文件(证书)\n\n```\nkeytool -genkey -alias terwer -keyalg RSA -keystore terwer.keystore\n```\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118200740263-274342170.jpg&w=500&h=500)\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118200738306-1089003635.jpg&w=500&h=500)\n\n2、配置 conf/server.xml\n\n```\n\n \n \n \n\n```\n\n3、使用https协议访问8443端口(https://localhost:8443)。\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118200738320-1295576902.jpg&w=500&h=500)\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118200740308-1199513315.jpg&w=500&h=500)\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118200740780-485253013.jpg&w=500&h=500)\n\n# Tomcat的性能优化策略\n\n系统性能的衡量指标,主要是响应时间和吞吐量。 \n\n1) 响应时间:执行某个操作的耗时;\n\n2) 吞吐量:系统在给定时间内能够支持的事务数量,单位为TPS(Transactions PerSecond的缩写,也 就是事务数/秒,一个事务是指一个客户机向服务器发送请求然后服务器做出反应的过程。\n\nTomcat优化从两个方面进行\n\n1)JVM虚拟机优化(优化内存模型) \n2)Tomcat自身配置的优化(比如是否使用了共享线程池?IO模型?)\n\n具体的效果需要根据生产环境调整到合适的参数\n\n## 虚拟机运行优化\n\nJava 虚拟机的运行优化主要是内存分配和垃圾回收策略的优化:\n\n* 内存直接影响服务的运行效率和吞吐量\n \n* 垃圾回收机制会不同程度地导致程序运行中断(垃圾回收策略不同,垃圾回收次数和回收效率都是\n* 不同的)\n\nJava虚拟机相关参数\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118200740824-905394955.jpg&w=500&h=500)\n\nJVM内存模型\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118200739501-1216949050.jpg&w=500&h=500)\n\n参数调整实例\n\n```\n JAVA_OPTS=\"-server -Xms2048m -Xmx2048m -XX:MetaspaceSize=256m -\nXX:MaxMetaspaceSize=512m\"\n```\n\n利用内存工具查看\n\n```\nps -ef|grep tomcat \njhsdb jmap --heap --pid 21336\n```\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118200741149-598608480.jpg&w=500&h=500)\n\n## 垃圾回收策略(GC策略)\n\n### 垃圾回收性能指标\n\n吞吐量:工作时间(排除GC时间)占总时间的百分比, 工作时间并不仅是程序运行的时间,还包 含内存分配时间。\n\n暂停时间:由垃圾回收导致的应用程序停止响应次数/时间。\n\n### 垃圾收集器\n\n1、串行收集器(Serial Collector)\n\n单线程执行所有的垃圾回收工作, 适用于单核CPU服务器 工作进程-----|(单线程)垃圾回收线程进行垃圾收集|---工作进程继续 \n\n2、并行收集器(Parallel Collector)\n\n工作进程-----|(多线程)垃圾回收线程进行垃圾收集|---工作进程继续\n\n又称为吞吐量收集器(关注吞吐量), 以并行的方式执行年轻代的垃圾回收, 该方式可以显著降 低垃圾回收的开销(指多条垃圾收集线程并行工作,但此时用户线程仍然处于等待状态)。适用于多 处理器或多线程硬件上运行的数据量较大的应用\n\n3、并发收集器(Concurrent Collector)\n\n以并发的方式执行大部分垃圾回收工作,以缩短垃圾回收的暂停时间。适用于那些响应时间优先于 吞吐量的应用, 因为该收集器虽然最小化了暂停时间(指用户线程与垃圾收集线程同时执行,但不一 定是并行的,可能会交替进行), 但是会降低应用程序的性能\n\n4、CMS收集器(Concurrent Mark Sweep Collector)\n\n并发标记清除收集器, 适用于那些更愿意缩短垃圾回收暂停时间并且负担的起与垃圾回收共享处\n理器资源的应用\n\n5、G1收集器(Garbage-First Garbage Collector)\n\n适用于大容量内存的多核服务器, 可以在满足垃圾回收暂停时间目标的同时, 以最大可能性实现 高吞吐量( JDK1.7之后)\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118200740597-1843854698.jpg&w=500&h=500)\n\n调整垃圾收集器\n\n```\nJAVA_OPTS=\"-XX:+UseConcMarkSweepGC\"\n```\n\n命令行打开 jconsole ,可以看到 jdk11 默认是 G1收集器\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118200740600-457115931.jpg&w=500&h=500)\n\n调整之后\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118200740780-1585031557.jpg&w=500&h=500)\n\n## Tomcat配置调优\n\nTomcat自身相关配置\n\n1、调整线程池\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118201742357-656409120.jpg&w=500&h=500)\n\n2、调整连接器\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118201742536-1955193913.jpg&w=500&h=500)\n\n3、禁用 AJP 连接器\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118201742300-193932424.jpg&w=500&h=500)\n\n\n4、调整I/O模式\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220118201742386-1883197867.jpg&w=500&h=500)\n\n可尝试使用 Apr IO模型,这个Apache底层库,依赖操作系统底层实现,性能较高\n\n5、动静分离\n\n可以使用Nginx+Tomcat相结合的部署方案,Nginx负责静态资源访问,Tomcat负责Jsp等动态资 源访问处理(因为Tomcat不擅⻓处理静态资源)。', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7942, 'nginx-yuan-li-shen-ru-pou-xi', 'Nginx原理深入剖析', '2022-01-19 01:46:24', '2022-01-19 01:47:20', '# Nginx基础\n\n## 什么是nginx\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220119014112183-720041123.jpg&w=500&h=500)\n\nNginx 是一个高性能的HTTP和反向代理web服务器,核心特点是占有内存少,并发能力强\n\n## Nginx得到应用场景\n\n1、Http服务器(Web服务器) \n\n性能非常高,非常注重效率,能够经受高负载的考验。\n\n支持50000个并发连接数,不仅如此,CPU和内存的占用也非常的低,10000个没有活动的连接才占用2.5M的内存。\n\n2、反向代理服务器 \n\n正向代理\n \n在浏览器中配置代理服务器的相关信息,通过代理服务器访问目标网站,代理服务器收到目标网站的响应之后,会把响应信息返回给我们自己的浏览器客户端\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220119014110659-1636529736.jpg&w=500&h=500)\n\n\n反向代理\n\n浏览器客户端发送请求到反向代理服务器(比如Nginx),由反向代理服务器选择原始服务器提供服务获取结果响应,最终再返回给客户端浏览器\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220119014110794-1155073345.jpg&w=500&h=500)\n\n3、负载均衡服务器\n\n负载均衡,当一个请求到来的时候(结合上图),Nginx反向代理服务器根据请求去找到一个原始服务器来处理当前请求,那么这叫做反向代理。那么,如果目标服务器有多台(比如上图中的tomcat1,tomcat2,tomcat3...),找哪一个目标服务器来处理当前请求呢,这样一个寻找确定的过程就叫做负载均衡。\n\n负载均衡就是为了解决高负载的问题。\n\n4、动静分离\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220119014111049-2045150282.jpg&w=500&h=500)\n\n## Nginx 的特点\n跨平台:Nginx可以在大多数类unix操作系统上编译运行,而且也有windows版本。Nginx的上手非常容易,配置也比较简单\n\n高并发,性能好\n\n稳定性也特别好,宕机概率很低\n\n## Nginx的安装\n\n上传nginx安装包到linux服务器,nginx安装包(.tar文件)\n\n本地虚拟机使用 openEuler\n\nPS:centos8以后停止维护( https://centos.org/news-and-events/1322-october-centos-dojo-videos/ ),可以使用华为开源的 openEuler 代替。也可以使用 https://rockylinux.org/ (还在开发中,目前8.5)\n\nhttps://repo.openeuler.org/openEuler-20.03-LTS-SP3/ISO/x86_64/openEuler-20.03-LTS-SP3-x86_64-dvd.iso\n\n安装openEuler\n\nhttps://www.cnblogs.com/thepoy/p/15405778.html\n\nNginx下载地址: http://nginx.org \n\n最新稳定版是 1.20.2\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220119014110667-297118141.jpg&w=500&h=500)\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220119014110797-2026766299.jpg&w=500&h=500)\n\n安装Nginx依赖,pcre、openssl、gcc、zlib(推荐使用yum源自动安装)\n\n```\nyum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel \n```\n\n解包Nginx软件包\n\n```\ntar -xvf nginx-1.20.2.tar.gz\n```\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220119014112321-568220778.jpg&w=500&h=500)\n\n进入解压之后的目录 nginx-1.20.2\n\n```\ncd nginx-1.20.2\n```\n\n命令行执行 `./configure`\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220119014111202-1925577662.jpg&w=500&h=500)\n\n命令行执行 `make`\n\n命令行执行 `make install` ,完毕之后在 `/usr/local/` 下会产生一个nginx目录\n\n进入sbin目录中,执行启动nginx命令\n\n```\ncd nginx/sbin\n./nginx\n```\n\n结果如下\n\n```\n[terwer@localhost nginx-1.20.2]$ cd /usr/local\n[terwer@localhost local]$ ls\nbin etc games include lib lib64 libexec nginx sbin share src\n[terwer@localhost local]$ cd nginx/sbin\n[terwer@localhost sbin]$ ls\nnginx\n[terwer@localhost sbin]$ sudo ./nginx\n[terwer@localhost sbin]$ \n```\n\n然后访问服务器的80端口(nginx默认监听80端口)\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220119014110925-1018618573.jpg&w=500&h=500)\n\n外部浏览器验证\n\n```\n# 通过下面的命令找到 openEuler 的ip\nip addr\n```\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220119014110701-245857199.jpg&w=500&h=500)\n\n## Nginx的主要命令\n\n`./nginx` 启动nginx\n\n`./nginx -s stop` 终止nginx(当然也可以找到nginx进程号,然后使用kill -9 杀掉nginx进程) \n\n`./nginx -s reload` (重新加载nginx.conf配置文件)\n\n# Nginx核心配置文件\n\nNginx的核心配置文件 `conf/nginx.conf` 包含三块内容:全局块、events块、http块\n\n## 全局块\n\n从配置文件开始到events块之间的内容,此处的配置影响nginx服务器整体的运行,比如worker进程的数量、错误日志的位置等\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220119014110707-1358742107.jpg&w=500&h=500)\n\n## events块\n\nevents块主要影响nginx服务器与用户的网络连接,比如worker_connections 1024,标识每个\nworkderprocess支持的最大连接数为1024\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220119014110440-1060258385.jpg&w=500&h=500)\n\n## http块\n\nhttp块是配置最频繁的部分,虚拟主机的配置,监听端口的配置,请求转发、反向代理、负载均衡 等\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220119014110917-86635039.jpg&w=500&h=500)\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220119014111053-815112286.jpg&w=500&h=500)\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220119014111160-1618485384.jpg&w=500&h=500)\n\n# 反向代理\n\n## 需求一\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220119014112413-568109228.jpg&w=500&h=500)\n\n## 需求一实现\n\n部署tomcat,保持默认监听8080端口 \n\n修改nginx配置,并重新加载\n\n修改nginx配置\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220119014110644-541839245.jpg&w=500&h=500)\n\n\n重新加载nginx配置\n\n./nginx -s reload\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220119014110992-300175064.jpg&w=500&h=500)\n\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220119014110952-145473907.jpg&w=500&h=500)\n\n\n## 需求二实现\n\n再部署一台tomcat,保持默认监听8081端口\n\n修改nginx配置,并重新加载\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220119014110748-1823515169.jpg&w=500&h=500)\n\n这里主要就是多location的使用,这里的nginx中server/location就好比tomcat中的 Host/Context\n\nlocation 语法如下:\n\n```\nlocation [=|~|~*|^~] /uri/ { ... }\n```\n\n在nginx配置文件中,location主要有这几种形式: \n\n1)正则匹配 location ~/lagou { } \n\n2)不区分大小写的正则匹配 location ~*/lagou { } \n\n3)匹配路径的前缀 location ^~/lagou { } \n\n4)精确匹配 location = /lagou { } \n\n5)普通路径前缀匹配 location /lagou { }\n\n优先级 4>3>2>1>5\n\n# 负载均衡\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220119014111073-1818562537.jpg&w=500&h=500)\n\n## Nginx负载均衡策略\n\n### 轮询\n\n默认策略,每个请求按时间顺序逐一分配到不同的服务器,如果某一个服务器下线,能自动剔除\n\n```\nupstream lagouServer{\n server 111.229.248.243:8080;\n server 111.229.248.243:8082;\n}\nlocation /abc {\n proxy_pass http://lagouServer/;\n}\n```\n\n### weight \n\nweight代表权重,默认每一个负载的服务器都为1,权重越高那么被分配的请求越多(用于服务器\n性能不均衡的场景)\n\n```\nupstream lagouServer{\n server 111.229.248.243:8080 weight=1;\n server 111.229.248.243:8082 weight=2;\n}\n```\n\n### ip_hash \n\n每个请求按照ip的hash结果分配,每一个客户端的请求会固定分配到同一个目标服务器处理,可\n以解决session问题\n\n```\nupstream lagouServer{\n ip_hash;\n server 111.229.248.243:8080;\n server 111.229.248.243:8082;\n}\n```\n\n# 动静分离\n\n动静分离就是讲动态资源和静态资源的请求处理分配到不同的服务器上,比较经典的组合就是 Nginx+Tomcat架构(Nginx处理静态资源请求,Tomcat处理动态资源请求),那么其实之前的讲解 中,Nginx反向代理目标服务器Tomcat,我们能看到目标服务器ROOT项目的index.jsp,这本身就是 Tomcat在处理动态资源请求了。\n\n所以,我们只需要配置静态资源访问即可。\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220119014111105-2110341179.jpg&w=500&h=500)\n\n# Nginx底层机制剖析\n\nNginx启动后,以daemon多进程方式在后台运行,包括一个Master进程和多个Worker进程,Master\n进程是领导,是老大,Worker进程是干活的小弟。\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220119014110748-1222922170.jpg&w=500&h=500)\n\n## master进程 \n\n主要是管理worker进程,比如:\n接收外界信号向各worker进程发送信号(./nginx -s reload) 监控worker进程的运行状态,当worker进程异常退出后Master进程会自动重新启动新的worker进程等\n \n## worker进程\n \nworker进程具体处理网络请求。多个worker进程之间是对等的,他们同等竞争来自客户端的请求,各进程互相之间是独立的。一个请求,只可能在一个worker进程中处理,一个worker进程, 不可能处理其它进程的请求。worker进程的个数是可以设置的,一般设置与机器cpu核数一致。\n\n## Nginx进程模型\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220119014111110-590669850.jpg&w=500&h=500)\n\n以 ./nginx -s reload 来说明nginx信号处理这部分 \n\n1)master进程对配置文件进行语法检查 \n\n2)尝试配置(比如修改了监听端口,那就尝试分配新的监听端口)\n\n3)尝试成功则使用新的配置,新建worker进程 \n\n4)新建成功,给旧的worker进程发送关闭消息 \n\n5)旧的worker进程收到信号会继续服务,直到把当前进程接收到的请求处理完毕后关闭,所以reload之后worker进程pid是发生了变化的\n\n![](https://images.weserv.nl/?url=https://img2020.cnblogs.com/blog/236099/202201/236099-20220119014110916-225508294.jpg&w=500&h=500)\n\n## worker进程处理请求部分的说明 \n\n例如,我们监听9003端口,一个请求到来时,如果有多个worker进程,那么每个worker进程都有\n可能处理这个链接。 \n\nmaster进程创建之后,会建立好需要监听的的socket,然后从master进程再fork出多个worker进程。所以,所有worker进程的监听描述符listenfd在新连接到来时都变得可读。\n\nnginx使用互斥锁来保证只有一个workder进程能够处理请求,拿到互斥锁的那个进程注册listenfd读事件,在读事件里调用accept接受该连接,然后解析、处理、返回客户端\n\n## nginx多进程模型好处\n\n每个worker进程都是独立的,不需要加锁,节省开销 \n\n每个worker进程都是独立的,互不影响,一个异常结束,其他的照样能提供服务 \n\n多进程模型为reload热部署机制提供了支撑', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7943, '', '', '2022-03-03 15:39:21', '2022-03-03 23:39:21', 'www.terwergreen.com 域名重新备案通过。', 1, 0, NULL, NULL, 'publish', 'essay', 1, 0); +INSERT INTO `posts` VALUES (7948, 'tomcat-de-ti-xi-jie-gou', 'Tomcat的体系结构2', '2022-03-07 07:26:00', '2022-03-08 01:44:14', '## Tomcat的顶层结构\n\nTomcat最顶层是Server服务器,Server服务器包含了多个Service。Server主要控制整个服务器,而Service负责对外提供服务。\n\n![](http://oss.terwergreen.com/bugucms/2022/03/07/16425607365917.jpg)\n\n\n## Tomcat的Service的架构\n\n每一个Service又由若干个组件构成。期中最重要的是连接器组件(Connector)和容器组件(Container)。\n\n除了核心组件,还有jasper组件负责jsp的解析,naming负责JNDI,Logging负责日志等。\n\n![](http://oss.terwergreen.com/bugucms/2022/03/07/16425615229956.jpg)\n\n其中,一个Service对应对个Connector和一个Container。\n\n## Connector组件Coypote的结构\n\n![](http://oss.terwergreen.com/bugucms/2022/03/07/16425621470356.jpg)\n\n连接器组件主要由EndPoint、Processor、Adaptor组成。\n\n当请求到达时,先由EndPoint通过传输层协议进行socket通信,然后由Process实现对应用层协议分处理,例如http/ajp等\n\n其中EndPoint和Processor主要由Protohandler进行实际的处理。\n\n最后由Adaptor适配器把Request转换成ServletRequest提供给日Servlet容器进行进一步处理。\n\n请求处理完成后,再由Adaptor将ServletResponse对象转换成Response对象,经过Procohandler\n进一步处理,最终把响应结果返回给浏览器。\n\n\n## Catania容器的结构\n\n![](http://oss.terwergreen.com/bugucms/2022/03/07/16425626225729.jpg)\n\nCatania容器包含了一个Engine,即Servlet容器。\n\n一个Engine包含多个Host,就是说可以为多个虚拟主机提供服务。\n\n一个Host对应多个Context,每个Context就代表一个应用。\n\n一个Context又包含多个Wrapper,每个Wrapper就对应了一个Servlet。\n', 1, 0, NULL, NULL, 'draft', 'post', 1, 0); +INSERT INTO `posts` VALUES (7951, 'shi-yongmetaweblogapi-shi-xian-wen-zhang-pi-liang', '使用metaWeblogApi实现文章批量发布', '2022-03-07 19:40:08', '2022-03-08 11:48:41', '\n\n> 2022/03/08 验证通过 \n> \n> 文章更新历史\n> \n> 2022/03/08 新增图床实现。\n> \n> 原文地址:http://www.terwergreen.com/post/shi-yongmetaweblogapi-shi-xian-wen-zhang-pi-liang.html\n\n## XML-RPC\n\n### XML-RPC的java实现\n\nhttps://tldp.org/HOWTO/XML-RPC-HOWTO/xmlrpc-howto-java.html\n\n### apache提供的api\n\nhttps://archive.apache.org/dist/ws/xmlrpc/binaries/apache-xmlrpc-3.1.3-bin.tar.gz\n\n备注:上面的实现太老了,最新可用的版本\n\nhttps://github.com/terwer/xmlrpc-metaweblog-api\n\n### maven仓库\n\n```xml\n\n\n org.apache.xmlrpc\n xmlrpc-server\n 3.1.3\n \n \n javax.servlet\n servlet-api\n \n \n\n```\n\n注意:需要排除 `servlet-api` ,否则会冲突。\n\n## 自定义实现XMLRpcServer\n\n### 入口\n\n在SpringBoot的入口函数中加入下面代码\n\n```java\npublic static final String CONSTANT_XMLRPC_NAME = \"/xmlrpc\";\n\n@SuppressWarnings({\"unchecked\", \"rawtypes\"})\n @Bean\n public ServletRegistrationBean registerServlet() {\n return new ServletRegistrationBean(\n new XmlRpcServlet(),\n CONSTANT_XMLRPC_NAME // xml-rpc访问接口\n );\n} \n```\n\n### SPI配置文件\n\n![16466561723423](http://oss.terwergreen.com/bugucms/2022/03/08/16466561723423.jpg)\n\n代码如下\n\n```properties\nblogger=com.terwergreen.bugucms.coresevice.xmlrpc.MetaWeblogImpl\nmetaWeblog=com.terwergreen.bugucms.coresevice.xmlrpc.MetaWeblogImpl\n```\n\n### metaWeblog接口定义\n\n```java\n/**\n * metaWeblogApi接口定义\n *\n * @name: IMetaWeblog\n * @author: terwer\n * @date: 2022-03-07 13:30\n **/\npublic interface IMetaWeblog {\n /**\n * 获取博客信息:blogger.getUsersBlogs\n * @param appKey\n * @param username\n * @param password\n * @return\n * @throws XmlRpcException\n */\n List> getUsersBlogs(String appKey, String username, String password) throws XmlRpcException;\n\n /**\n * 发布博客文章:metaWeblog.newPost\n * @param blogid\n * @param username\n * @param password\n * @param post\n * @param publish\n * @return\n * @throws XmlRpcException\n */\n String newPost(String blogid, String username, String password, Map post, boolean publish) throws XmlRpcException;\n\n /**\n * 编辑博客文章:metaWeblog.editPost\n * @param postid\n * @param username\n * @param password\n * @param post\n * @param publish\n * @return\n * @throws XmlRpcException\n */\n boolean editPost(String postid, String username, String password, Map post, boolean publish) throws XmlRpcException;\n\n /**\n * 获取博客文章:metaWeblog.getPost\n * @param postid\n * @param username\n * @param password\n * @return\n * @throws XmlRpcException\n */\n Map getPost(String postid, String username, String password) throws XmlRpcException;\n\n /**\n * 获取博客分类:metaWeblog.getCategories\n * @param blogid\n * @param username\n * @param password\n * @return\n * @throws XmlRpcException\n */\n List> getCategories(String blogid, String username, String password) throws XmlRpcException;\n\n /**\n * 获取最近的文章列表:metaWeblog.getRecentPosts\n * @param blogid\n * @param username\n * @param password\n * @param numberOfPosts\n * @return\n * @throws XmlRpcException\n */\n List> getRecentPosts(String blogid, String username, String password, int numberOfPosts) throws XmlRpcException;\n\n /**\n * 上传媒体对象:metaWeblog.newMediaObject\n * @param blogid\n * @param username\n * @param password\n * @param post\n * @return\n * @throws XmlRpcException\n */\n Map newMediaObject(String blogid, String username, String password, Map post) throws XmlRpcException;\n}\n```\n\n### 接口实现\n\n```java\n/**\n * metaWeblogApi的具体实现\n *\n * @name: MetaWeblogImpl\n * @author: terwer\n * @date: 2022-03-07 14:09\n **/\npublic class MetaWeblogImpl implements IMetaWeblog {\n private static final Logger logger = LoggerFactory.getLogger(MetaWeblogImpl.class);\n\n private CommonService commonService;\n private Object userService;\n\n public CommonService getCommonService() {\n if (commonService == null) {\n commonService = SpringBeanUtils.getBean(CommonService.class);\n }\n return commonService;\n }\n\n public Object getUserService() {\n if (userService == null) {\n userService = (UserDetailsService) SpringBeanUtils.getBean(\"userService\");\n // userService = SpringBeanUtils.getBean(\"com.terwergreen.plugins.auth.service.impl.UserService\");\n }\n return userService;\n }\n\n public MetaWeblogImpl() {\n logger.info(\"容器中注册MetaWeblogImpl\");\n }\n\n private Map isValid(String username, String password) throws XmlRpcNotAuthorizedException {\n logger.info(\"username: {}, password: {}\", username, password);\n Object userService = getUserService();\n Map rtnResult = (Map) ReflectUtil.invoke(userService, \"isValid\", new Class[]{String.class, String.class},\n new Object[]{username, password});\n boolean isValid = (boolean) rtnResult.get(\"matches\");\n logger.info(\"isValid = {}\", isValid);\n if (!isValid) {\n throw new XmlRpcNotAuthorizedException(\"账号或密码有误\");\n }\n return rtnResult;\n }\n\n public List> getUsersBlogs(String appKey, String username, String password) throws XmlRpcException {\n logger.info(\"[blogger.getUsersBlogs] -> appKey: {}, username: {}, password: {}\", appKey, username, password);\n isValid(username, password);\n\n SiteConfig siteConfig = getCommonService().getSiteConfig();\n\n List> usersBlogs = new ArrayList<>();\n Map blogInfo = new HashMap<>();\n blogInfo.put(\"blogid\", \"BuguCMS\");\n blogInfo.put(\"url\", siteConfig.getWeburl());\n blogInfo.put(\"blogName\", siteConfig.getWebname());\n usersBlogs.add(blogInfo);\n\n return usersBlogs;\n }\n\n @Override\n public String newPost(String blogid, String username, String password, Map post, boolean publish) throws XmlRpcException {\n // logger.info(\"metaWeblog.newPost -> blogid: {}, post: {}, publish: {}\", blogid, JSON.toJSONString(post), publish);\n logger.info(\"metaWeblog.newPost -> blogid: {}, publish: {}\", blogid, publish);\n Map rtnResult = isValid(username, password);\n\n JSONObject postJson = JSONObject.parseObject(JSON.toJSONString(post));\n // logger.debug(\"postJson = {}\", postJson);\n\n Integer postId = 0;\n Object bean = SpringBeanUtils.getBean(\"com.terwergreen.plugins.blog.service.impl.PostServiceImpl\");\n Map pramMap = new HashMap();\n try {\n BugucmsPluginManager bugucmsPluginManager = SpringBeanUtils.getBean(BugucmsPluginManager.class);\n ClassLoader pluginClassLoader = bugucmsPluginManager.getPlugin(\"blog-plugin\").getPluginClassLoader();\n Class PostClazz = Class.forName(\"com.terwergreen.plugins.blog.pojo.Post\", true, pluginClassLoader);\n\n Object postObj = PostClazz.newInstance();\n // ==========\n // 数据转换开始\n // ArticleCategory ac = getCategory(postJson.getJSONArray(\"categories\"));\n // article.setCategory(ac);\n PropertyUtils.setProperty(postObj, \"postTitle\", postJson.getString(\"title\"));\n PropertyUtils.setProperty(postObj, \"postRawContent\", postJson.getString(\"description\"));\n // article.setKeywords(postJson.getString(\"mt_keywords\"));\n PropertyUtils.setProperty(postObj, \"postSlug\", postJson.getString(\"wp_slug\"));\n PropertyUtils.setProperty(postObj, \"postStatus\", postJson.getString(\"post_status\"));\n PropertyUtils.setProperty(postObj, \"postDate\", postJson.getDate(\"dateCreated\"));\n // post page essay note\n PropertyUtils.setProperty(postObj, \"postType\", \"post\");\n PropertyUtils.setProperty(postObj, \"postAuthor\", rtnResult.get(\"userId\"));\n // 数据转换结束\n // ==========\n\n postId = (Integer) ReflectUtil.invoke(bean, \"newPost\", new Class[]{PostClazz}, new Object[]{postObj});\n logger.info(\"postId = {}\", postId);\n } catch (Exception e) {\n e.printStackTrace();\n throw new XmlRpcException(500, e.getMessage());\n }\n\n return postId + \"\";\n }\n\n @Override\n public boolean editPost(String postid, String username, String password, Map post, boolean publish) throws XmlRpcException {\n // logger.info(\"metaWeblog.editPost -> postid: {}, post: {}\", postid, JSON.toJSONString(post));\n logger.info(\"metaWeblog.editPost -> postid: {}\", postid);\n\n Map rtnResult = isValid(username, password);\n\n JSONObject postJson = JSONObject.parseObject(JSON.toJSONString(post));\n // logger.debug(\"postJson = {}\", postJson);\n\n boolean flag = false;\n Object bean = SpringBeanUtils.getBean(\"com.terwergreen.plugins.blog.service.impl.PostServiceImpl\");\n Map pramMap = new HashMap();\n try {\n BugucmsPluginManager bugucmsPluginManager = SpringBeanUtils.getBean(BugucmsPluginManager.class);\n ClassLoader pluginClassLoader = bugucmsPluginManager.getPlugin(\"blog-plugin\").getPluginClassLoader();\n Class PostClazz = Class.forName(\"com.terwergreen.plugins.blog.pojo.Post\", true, pluginClassLoader);\n\n Object postObj = PostClazz.newInstance();\n // ==========\n // 数据转换开始\n // ArticleCategory ac = getCategory(postJson.getJSONArray(\"categories\"));\n // article.setCategory(ac);\n PropertyUtils.setProperty(postObj, \"postId\", Integer.valueOf(postid));\n PropertyUtils.setProperty(postObj, \"postTitle\", postJson.getString(\"title\"));\n PropertyUtils.setProperty(postObj, \"postRawContent\", postJson.getString(\"description\"));\n // article.setKeywords(postJson.getString(\"mt_keywords\"));\n PropertyUtils.setProperty(postObj, \"postSlug\", postJson.getString(\"wp_slug\"));\n PropertyUtils.setProperty(postObj, \"postStatus\", postJson.getString(\"post_status\"));\n PropertyUtils.setProperty(postObj, \"postDate\", postJson.getDate(\"dateCreated\"));\n // post page essay note\n PropertyUtils.setProperty(postObj, \"postType\", \"post\");\n PropertyUtils.setProperty(postObj, \"postAuthor\", rtnResult.get(\"userId\"));\n // 数据转换结束\n // ==========\n\n flag = (boolean) ReflectUtil.invoke(bean, \"editPostById\", new Class[]{PostClazz}, new Object[]{postObj});\n logger.info(\"flag = {}\", flag);\n } catch (Exception e) {\n e.printStackTrace();\n throw new XmlRpcException(500, e.getMessage());\n }\n\n return flag;\n }\n\n @Override\n public Map getPost(String postid, String username, String password) throws XmlRpcException {\n logger.info(\"metaWeblog.getPost -> postid: {}\", postid);\n isValid(username, password);\n\n Map rtnResult = isValid(username, password);\n\n Map post = new HashMap<>();\n Object bean = SpringBeanUtils.getBean(\"com.terwergreen.plugins.blog.service.impl.PostServiceImpl\");\n Map pramMap = new HashMap();\n try {\n BugucmsPluginManager bugucmsPluginManager = SpringBeanUtils.getBean(BugucmsPluginManager.class);\n ClassLoader pluginClassLoader = bugucmsPluginManager.getPlugin(\"blog-plugin\").getPluginClassLoader();\n Class PostClazz = Class.forName(\"com.terwergreen.plugins.blog.pojo.Post\", true, pluginClassLoader);\n\n Object postObj = ReflectUtil.invoke(bean, \"getPostById\", new Class[]{Integer.class}, new Object[]{Integer.valueOf(postid)});\n\n // ==========\n // 数据转换开始\n // ArticleCategory ac = getCategory(postJson.getJSONArray(\"categories\"));\n // article.setCategory(ac);\n post.put(\"title\", PropertyUtils.getProperty(postObj, \"postTitle\"));\n post.put(\"description\", PropertyUtils.getProperty(postObj, \"postRawContent\"));\n // article.setKeywords(postJson.getString(\"mt_keywords\"));\n post.put(\"wp_slug\", PropertyUtils.getProperty(postObj, \"postSlug\"));\n post.put(\"post_status\", PropertyUtils.getProperty(postObj, \"postStatus\"));\n post.put(\"dateCreated\", PropertyUtils.getProperty(postObj, \"postDate\"));\n // post page essay note\n post.put(\"post\", PropertyUtils.getProperty(postObj, \"postType\"));\n // 数据转换结束\n // ==========\n } catch (Exception e) {\n e.printStackTrace();\n throw new XmlRpcException(500, e.getMessage());\n }\n\n return post;\n }\n\n @Override\n public List> getCategories(String blogid, String username, String password) throws XmlRpcException {\n logger.info(\"metaWeblog.getCategories -> blogid: {}\", blogid);\n\n return new ArrayList<>();\n }\n\n @Override\n public List> getRecentPosts(String blogid, String username, String password, int numberOfPosts) throws XmlRpcException {\n logger.info(\"metaWeblog.getRecentPosts -> blogid: {}, numberOfPosts: {}\", blogid, numberOfPosts);\n\n// Object bean = SpringBeanUtils.getBean(\"com.terwergreen.plugins.blog.service.impl.PostServiceImpl\");\n// Map pramMap = new HashMap();\n// Object posts = ReflectUtil.invoke(bean, \"getRecentPosts\", new Class[]{Map.class}, new Object[]{pramMap});\n// System.out.println(\"posts = \" + posts);\n \n return null;\n }\n\n @Override\n public Map newMediaObject(String blogid, String username, String password, Map post) throws XmlRpcException {\n logger.info(\"metaWeblog.newMediaObject -> blogid: {}, post: {}\", blogid, JSON.toJSONString(post));\n\n return null;\n }\n}\n```\n\n至此,RPCServer集成完毕。\n\n### 图床支持\n\n实现 `newMediaObject` 即可,代码如下:\n\n```java\n@Override\npublic Map newMediaObject(String blogid, String username, String password, Map post) throws XmlRpcException {\n logger.info(\"metaWeblog.newMediaObject -> blogid: {}\", blogid);\n\n isValid(username, password);\n\n Map urlData = new HashMap<>();\n\n try {\n String retUrl = \"http://oss.terwergreen.com/%s\";\n String name = post.get(\"name\").toString();\n // {year}/{mon}/{day}/{filename}{.suffix}\n Date now = new Date();\n SimpleDateFormat sdf = new SimpleDateFormat(\"yyyy/MM/dd\");\n String forder = sdf.format(now);\n System.out.println(\"forder = \" + forder);\n String fileName = \"bugucms/\" + forder + \"/\" + name;\n String url = String.format(retUrl, fileName);\n\n byte[] bits = (byte[]) post.get(\"bits\");\n logger.info(\"准备上传图片,url = \" + url);\n // 开始上传图片\n OssManager manager = OssManager.getInstance();\n manager.upload(fileName, bits);\n\n // 水印\n // String watermark = String.format(\"?x-oss-process=%s\", \"image/auto-orient,1/quality,q_90/format,jpg/watermark,image_YnVndWNtcy9sb2dvLWRhcmsucG5nP3gtb3NzLXByb2Nlc3M9aW1hZ2UvcmVzaXplLFBfNjI,g_se,x_10,y_10\");\n // String markedUrl = url + watermark;\n\n urlData.put(\"url\", url);\n } catch (Exception e) {\n e.printStackTrace();\n logger.error(\"图片上传错误\", e);\n }\n\n logger.info(\"urlData = {}\", urlData);\n return urlData;\n}\n```\n\n', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7952, 'session-yi-zhi-xing-wen-ti-ji-jie-jue-fang-an', 'Session一致性问题及解决方案', '2022-02-09 02:18:55', '2022-03-08 12:27:51', '\n\n![image-20220308122157489](https://raw.githubusercontent.com/terwer/upload/main/img/20220308122225.png)\n\n## Session问题原因分析\n\n从根本上来说是因为Http协议是无状态的协议。客户端和服务端在某次会话中产 生的数据不会被保留下来,所以第二次请求服务端无法认识到你曾经来过, Http为什么要设计为无状态 协议?早期都是静态⻚面无所谓有无状态,后来有动态的内容更丰富,就需要有状态,出现了两种用于 保持Http状态的技术,那就是Cookie和Session。\n\n场景:nginx默认轮询策略\n\n![](https://raw.githubusercontent.com/terwer/upload/main/img/20220308122311.jpeg)\n\n\n## Session一致性的方案\n\n### Nginx的 IP_Hash 策略(可以使用) \n\n同一个客户端IP的请求都会被路由到同一个目标服务器,也叫做会话粘滞 \n\n优点:\n\n配置简单,不入侵应用,不需要额外修改代码\n\n缺点:\n服务器重启Session丢失 \n\n存在单点负载高的⻛险 单点故障问题\n\n### Session复制(不推荐) \n\n也即,多个tomcat之间通过修改配置文件,达到Session之间的复制\n\n\n![](https://raw.githubusercontent.com/terwer/upload/main/img/20220308122338.jpeg)\n\n优点:\n\n不入侵应用\n\n便于服务器水平扩展 能适应各种负载均衡策略 服务器重启或者宕机不会造成Session丢失\n\n缺点:\n\n 性能低\n\n 内存消耗\n\n 不能存储太多数据,否则数据越多越影响性能\n\n 延迟性\n\n### Session共享,Session集中存储(推荐)\n\nSession的本质就是缓存,那Session数据为什么不交给专业的缓存中间件呢?比如Redis\n\n![](https://raw.githubusercontent.com/terwer/upload/main/img/20220308122351.jpeg)\n\n\n优点:\n\n能适应各种负载均衡策略 服务器重启或者宕机不会造成Session丢失扩展能力强\n\n适合大集群数量使用\n\n缺点:\n\n对应用有入侵,引入了和Redis的交互代码\n\n## redis解决Session问题实例\n\n引入jar\n\n```\n\n org.springframework.boot\n spring-boot-starter-data-redis\n\n\n org.springframework.session\n spring-session-data-redis\n\n```\n\n配置redis\n\n```\nspring.redis.database=0\nspring.redis.host=127.0.0.1\nspring.redis.port=6379\n```\n\n添加注解\n\n## redis解决Session问题原理\n\n![](https://raw.githubusercontent.com/terwer/upload/main/img/20220308122400.jpeg)', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7953, 'yi-zhi-xinghash-wen-ti-ji-jie-jue-fang-an', '一致性hash问题及解决方案', '2022-01-19 02:16:46', '2022-03-08 12:34:38', '\n\n# 分布式和集群的区别\n\n分布式一定是集群,但是集群不一定是分布式。集群是多个实例一起工作,分布式啊将一个系统拆分,拆分之后就是多个实例。**复制性的集群不是拆分,是复制。**\n\n更清晰的解释\n\nhttps://cloud.tencent.com/developer/article/1579435\n\n大白话的解释\n\n![](https://raw.githubusercontent.com/terwer/upload/main/img/20220308123123.jpeg)\n\n专业案例解释\n\n![](https://raw.githubusercontent.com/terwer/upload/main/img/20220308123202.jpeg)\n\n\n# hash算法回顾\n\n## 什么是hash算法\n\n哈希算法(Hash)又称摘要算法(Digest),它的作用是:对任意一组输入数据进行计算,得到一个固定长度的输出摘要。\n\nWikiPedia的解释\n\nA hash function is any function that can be used to map data of arbitrary size to fixed-size values.\n\n## 为什么要使用hash\n\nHash算法较多的应用在数据存储和查找领域。最经典的就是Hash表,它的查询效率非常之高,其中的 哈希算法如果设计的比较ok的话,那么Hash表的数据查询时间复杂度可以接近于O(1)。\n\n## hash算法实例\n\n### 需求\n\n提供一组数据 1,5,7,6,3,4,8,对这组数据进行存储,然后随便给定一个数n,请你判断n是否存在于刚才的数据集中\n\n### 分析与实现\n\n#### 顺序查找法\n直接遍历\n```\nlist:List[1,5,7,6,3,4,8]\n// 通过循环判断来实现\nfor(int element: list) {\n if(element == n) {\n // 如果相等,说明n存在于数据集中\n }\n}\n```\n代码如下\n\n```\n/**\n * @name: FindNum\n * @author: terwer\n * @date: 2022-01-26 14:57\n **/\npublic class FindNum {\n public static void main(String[] args) {\n int[] nums = new int[]{1, 5, 7, 6, 3, 4, 8};\n\n int num = 3;\n boolean result = isExist1(nums, num);\n System.out.println(num + \"是否存在:\" + result);\n }\n\n\n // 顺序查找\n public static boolean isExist1(int[] nums, int n) {\n for (int num : nums) {\n if (num == n) {\n return true;\n }\n }\n\n return false;\n }\n}\n```\n\n缺点:通过循环来完成,比较原始,效率不高\n#### 折半查找法(二分查找)\n\n```\n// 折半查找\npublic static boolean isExist2(int[] nums, int target) {\n System.out.println(\"折半查找\");\n // 先排序,jdk使用的是快速排序\n Arrays.sort(nums);\n\n int left = 0;\n int right = nums.length - 1;\n\n while (left <= right) {\n int middle = left + (right - left) / 2;\n\n if (target == nums[middle]) {\n return true;\n } else if (target < nums[middle]) {\n right = middle - 1;\n } else if (target > nums[middle]) {\n left = middle - 1;\n }\n }\n\n return false;\n}\n```\n\n排序之后折半查找,相对于顺序查找法会提高一些效率,但是效率也并不是特别好\n\n缺点:还是需要循环\n\n#### 直接寻址法\n\n直接把数据和数组的下标绑定到一起,查找的时候,直接array[n]就取出了数据\n\n优点:速度快,一次查找得到结果\n\n缺点\n\n1、浪费空间。例如,1,2,100\n\n2、有重复数据的时候,存储不下。例如,1,2,3,3,2,1,6\n\n#### hash寻址法\n\n如果数据是3,5,7,12306,一共4个数据,可以用下面方式保存\n\n![](https://raw.githubusercontent.com/terwer/upload/main/img/20220308123217.jpeg)\n\n\n对数据求模 (数据%空间位置数) 。\n\n这是一个hash算法,叫做除留余数法\n\n#### 开放寻址法\n\n![](https://raw.githubusercontent.com/terwer/upload/main/img/20220308123222.jpeg)\n\n1放进去了,6再来的时候,向前或者向后找空闲位置存放\n\n缺点:如果数组长度固定,可能出现向前或者向后查找也存储不下的情况\n\n#### 拉链法\n\n![](https://raw.githubusercontent.com/terwer/upload/main/img/20220308123228.jpeg)\n\n可以在元素的地方放一个链表。\n\nHash表的查询效率高不高取决于Hash算法,hash算法的理想实现是能够让数据平均分布,既能够节省空间又能提高查询效率。\n\n### 常见的hash算法\n\n- [ ] 除留余数法 3%5\n\n- [ ] 线性构造Hash算法 \n\n直接寻址法也是一种构造Hash的方式,只不过更简单,表达式:H(key)=key 比如H(key)=a*key + b(a,b是常量)\n\n- [ ] hashcode其实也是通过一个Hash算法得来的\n\n## hash算法应用场景\n\nHash算法在分布式集群架构中的应用场景 \n\nHash算法在很多分布式集群产品中都有应用,比如分布式集群架构Redis、Hadoop、ElasticSearch,\nMysql分库分表,Nginx负载均衡等\n\n最主要的应用场景\n\n1. 请求的负载均衡(比如nginx的ip_hash策略)\n\nNginx的IP_hash策略可以在客户端ip不变的情况下,将其发出的请求始终路由到同一个目标服务器上,实现会话粘滞,避免处理session共享问题\n\n如果没有IP_hash策略,那么如何实现会话粘滞? 可以维护一张映射表,存储客户端IP或者sessionid与具体目标服务器的映射关系 \n\n\n\n缺点\n\n1)那么,在客户端很多的情况下,映射表非常大,浪费内存空间 \n\n2)客户端上下线,目标服务器上下线,都会导致重新维护映射表,映射表维护成本很大\n\n如果使用哈希算法,事情就简单很多,我们可以对ip地址或者sessionid进行计算哈希值,哈希值与服务 器数量进行取模运算,得到的值就是当前请求应该被路由到的服务器编号,如此,同一个客户端ip发送过来的请求就可以路由到同一个目标服务器,实现会话粘滞。\n\n1. 分布式存储\n\n以分布式内存数据库Redis为例,集群中有redis1,redis2,redis3 三台Redis服务器\n那么,在进行数据存储时,数据存储到哪个服务器当中呢?\n\n针对key进行hash处理 hash(key1)%3=index, 使用余数index锁定存储的具体服务器节点\n\n## 普通hash算法存在的问题\n\n以ip_hash为例,假定下载用户ip固定没有发生改变,现在tomcat3出现 了问题,down机了,服务器数量由3个变为了2个,之前所有的求模都需要重新计算。\n\n![](https://raw.githubusercontent.com/terwer/upload/main/img/20220308123237.jpeg)\n\n如果在真实生产情况下,后台服务器很多台,客户端也有很多,那么影响是很大的,缩容和扩容都会存\n在这样的问题,大量用户的请求会被路由到其他的目标服务器处理,用户在原来服务器中的会话都会丢\n失。\n\n## 一致性hash算法\n\n![](https://raw.githubusercontent.com/terwer/upload/main/img/20220308123242.jpeg)\n\n首先有一条直线,直线开头和结尾分别定为为1和2的32次方减1,这相当于一个地址,对于这样一条线,弯过来构成一个圆环形成闭环,这样的一个圆环称为hash环。\n\n我们把服务器的ip或者主机名求hash值然后对应到hash环上,那么针对客户端用户,也根据它的ip进行hash求值,对应到环上某个位置。\n\n然后如何确定一个客户端路由到哪个服务器处理呢?按照顺时针方向找最近的服务器节点。\n\n![](https://raw.githubusercontent.com/terwer/upload/main/img/20220308123248.jpeg)\n\n假如将服务器3下线,服务器3下线后,原来路由到3的客户端重新路由到服务器4,对于其他客户端没有 影响只是这一小部分受影响(请求的迁移达到了最小,这样的算法对分布式集群来说非常合适的,避免 \n了大量请求迁移 )\n\n![](https://raw.githubusercontent.com/terwer/upload/main/img/20220308123254.jpeg)\n\n增加服务器5之后,原来路由到3的部分客户端路由到新增服务器5上,对于其他客户端没有影响只是这 一小部分受影响(请求的迁移达到了最小,这样的算法对分布式集群来说非常合适的,避免了大量请求迁移 )\n\n![](https://raw.githubusercontent.com/terwer/upload/main/img/20220308123300.jpeg)\n\n\n* 每一台服务器负责一段,一致性哈希算法对于节点的增减都只需重定位环空间中的一小部分数据,具有较好的容错性和可扩展性。\n\n缺点:数据的倾斜问题\n\n一致性哈希算法在服务节点太少时,容易因为节点分部不均匀而造成数据倾斜问题。例如系统中 只有两台服务器,其环分布如下,节点2只能负责非常小的一段,大量的客户端\n请求落在了节点1上,这就是数据(请求)倾斜问题\n\n* 为了解决这种数据倾斜问题,一致性哈希算法引入了虚拟节点机制,即对每一个服务节点计算多个哈希,每个计算结果位置都放置一个此服务节点,称为虚拟节点。\n\n具体做法可以在服务器ip或主机名的后面增加编号来实现。比如,可以为每台服务器计算三个虚拟节点,于是可以分别计算 “节点1的ip#1”、“节点1的ip#2”、“节点1的ip#3”、“节点2的ip#1”、“节点2的 ip#2”、“节点2的ip#3”的哈希值,于是形成六个虚拟节点,当客户端被路由到虚拟节点的时候其实是被 路由到该虚拟节点所对应的真实节点\n\n![](https://raw.githubusercontent.com/terwer/upload/main/img/20220308123305.jpeg)\n\n## 手写实现一致性hash算法\n\n* 普通Hash算法实现\n\n```\n/**\n * 普通hash算法\n *\n * @name: GeneraHash\n * @author: terwer\n * @date: 2022-01-26 15:46\n **/\npublic class GeneraHash {\n public static void main(String[] args) {\n // 定义客户端IP\n String[] clients = new String[]{\"10.78.12.3\", \"113.25.63.1\", \"126.12.3.8\"};\n\n // 定义服务器数量\n int serverCount = 5;// (编号对应0,1,2)\n\n // hash(ip)%node_counts=index //根据index锁定应该路由到的tomcat服务器\n for (String client : clients) {\n\n int hash = Math.abs(client.hashCode());\n int index = hash % serverCount;\n System.out.println(\"客户端:\" + client + \" 被路由到服务器编号为:\" + index);\n }\n }\n}\n```\n\n* 一致性Hash算法实现(不含虚拟节点)\n\n```\n/**\n * @name: 一致性Hash算法不含虚拟节点\n * @author: terwer\n * @date: 2022-01-26 15:52\n **/\npublic class ConsitanceHashNoVirtual {\n public static void main(String[] args) {\n //step1 初始化:把服务器节点IP的哈希值对应到哈希环上 // 定义服务器ip\n String[] tomcatServers = new String[]{\"123.111.0.0\", \"123.101.3.1\", \"111.20.35.2\", \"123.98.26.3\"};\n SortedMap hashServerMap = new TreeMap<>();\n\n for (String tomcatServer : tomcatServers) {\n // 求出每一个ip的hash值,对应到hash环上,存储hash值与ip的对应关系\n int serverHash = Math.abs(tomcatServer.hashCode());\n // 存储hash值与ip的对应关系\n hashServerMap.put(serverHash, tomcatServer);\n }\n\n //step2 针对客户端IP求出hash值\n // 定义客户端IP\n String[] clients = new String[]{\"10.78.12.3\", \"113.25.63.1\", \"126.12.3.8\"};\n for (String client : clients) {\n int clientHash = Math.abs(client.hashCode());\n //step3 针对客户端,找到能够处理当前客户端请求的服务器(哈希环上顺时针最近)\n // 根据客户端ip的哈希值去找出哪一个服务器节点能够处理()\n SortedMap integerStringSortedMap =\n hashServerMap.tailMap(clientHash);\n if (integerStringSortedMap.isEmpty()) {\n // 取哈希环上的顺时针第一台服务器\n Integer firstKey = hashServerMap.firstKey();\n System.out.println(\"==========>>>>客户端:\" + client + \" 被路由到服务器:\" + hashServerMap.get(firstKey));\n } else {\n Integer firstKey = integerStringSortedMap.firstKey();\n System.out.println(\"==========>>>>客户端:\" + client + \" 被路由到服务器:\" + hashServerMap.get(firstKey));\n }\n }\n }\n}\n```\n\n* 一致性hash包含虚拟节点\n\n```\n/**\n * @name: 一致性hash包括虚拟节点\n * @author: terwer\n * @date: 2022-01-26 15:58\n **/\npublic class ConstanceHashVirtual {\n public static void main(String[] args) {\n //step1 初始化:把服务器节点IP的哈希值对应到哈希环上\n // 定义服务器ip\n String[] tomcatServers = new String[]{\"123.111.0.0\", \"123.101.3.1\", \"111.20.35.2\", \"123.98.26.3\"};\n SortedMap hashServerMap = new TreeMap<>();\n // 定义针对每个真实服务器虚拟出来⼏个节点\n int virtaulCount = 3;\n for (String tomcatServer : tomcatServers) {\n // 求出每⼀个ip的hash值,对应到hash环上,存储hash值与ip的对应关系\n int serverHash = Math.abs(tomcatServer.hashCode());\n // 存储hash值与ip的对应关系\n hashServerMap.put(serverHash, tomcatServer);\n // 处理虚拟节点\n for (int i = 0; i < virtaulCount; i++) {\n int virtualHash = Math.abs((tomcatServer + \"#\" + i).hashCode());\n hashServerMap.put(virtualHash, \"----由虚拟节点\" + i + \"映射过来的请求:\" + tomcatServer);\n }\n }\n\n //step2 针对客户端IP求出hash值\n // 定义客户端IP\n String[] clients = new String[]{\"10.78.12.3\", \"113.25.63.1\", \"126.12.3.8\"};\n for (String client : clients) {\n int clientHash = Math.abs(client.hashCode());\n //step3 针对客户端,找到能够处理当前客户端请求的服务器(哈希环上顺时针最近)\n // 根据客户端ip的哈希值去找出哪⼀个服务器节点能够处理()\n SortedMap integerStringSortedMap =\n hashServerMap.tailMap(clientHash);\n if (integerStringSortedMap.isEmpty()) {\n // 取哈希环上的顺时针第⼀台服务器\n Integer firstKey = hashServerMap.firstKey();\n System.out.println(\"==========>>>>客户端:\" + client + \" 被路由到服务器:\" + hashServerMap.get(firstKey));\n } else {\n Integer firstKey = integerStringSortedMap.firstKey();\n System.out.println(\"==========>>>>客户端:\" + client + \" 被路由到服务器:\" + hashServerMap.get(firstKey));\n }\n }\n }\n}\n```\n\n## Nginx配置一致性hash负载均衡策略\n\nngx_http_upstream_consistent_hash 模块是一个负载均衡器,使用一个内部一致性hash算法来选择\n合适的后端节点。\n\n该模块可以根据配置参数采取不同的方式将请求均匀映射到后端机器,\n\nconsistent_hash $remote_addr:可以根据客户端ip映射\n\nconsistent_hash $request_uri:根据客户端请求的uri映射\n\nconsistent_hash $args:根据客户端携带的参数进行映\n\nngx_http_upstream_consistent_hash 模块是一个第三方模块,需要我们下载安装后使用\n\n1、github下载nginx一致性hash负载均衡模块 https://github.com/replay/ngx_http_consistent_hash\n\n2、将下载的压缩包上传到nginx服务器,并解压 \n\n3、我们已经编译安装过nginx,此时进入当时nginx的源码目录,执行如下命令 \n\n```\n./configure —add-module=/root/ngx_http_consistent_hash-master\nmake\nmake install\n```\n\n4、在nginx.conf文件中配置即可\n\n```\n# 配置负载均衡\nupstream loginServer {\n consistent_hash $request_uri;\n server 127.0.0.1:8080;\n server 127.0.0.1:8081;\n}\n```', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7954, 'zi-ding-yirpc-kuang-jia', '自定义RPC框架', '2022-03-01 06:43:08', '2022-03-14 02:34:13', '\n> 2022/03/14 校对完成 \n>\n> 文章更新历史\n> \n> 2022/03/14 初稿。\n>\n> 原文地址:[http://www.terwergreen.com/post/zi-ding-yirpc-kuang-jia.html](http://www.terwergreen.com/post/zi-ding-yirpc-kuang-jia.html)\n## 分布式架构网络通信\n\n分布式的基础问题是远程服务是怎么通讯的。\n\n`java` 领域有很多可实现远程通讯的技术,例如:`RMI` 、`Hessian` 、`SOAP` 、`ESB` 和 `JMS` 等。\n\n### 远程通讯技术\n\n#### RMI\n\nJDK的RMI文档:https://docs.oracle.com/javase/8/docs/technotes/guides/rmi/\n\n#### Hessian \n\nHessian官网:http://hessian.caucho.com/\n\n#### SOAP\n\nSOAP:https://zh.wikipedia.org/wiki/%E7%AE%80%E5%8D%95%E5%AF%B9%E8%B1%A1%E8%AE%BF%E9%97%AE%E5%8D%8F%E8%AE%AE\n\n- WSDL WS-* are language-agnostic.\n\n- JAX-WS are Java standard to build web service.\n\n- [Apache CXF](http://cxf.apache.org/docs/why-cxf.html) and [Apache Axis 2](http://axis.apache.org/axis2/java/core/) are two implementations of JAX-WS. They also offer JAX-RS implementations so that you can build Restful services.\n\n- CXF has better integration with Spring, and Camel([camel-cxf](http://camel.apache.org/components.html)). And Axis 2 seems not have a active release.\n\n- https://github.com/eclipse-ee4j/jersey\n\n- https://cxf.apache.org/index.html\n\n- https://github.com/apache/axis-axis2-java-core\n\n#### ESB\n\nESB:https://zh.wikipedia.org/wiki/%E4%BC%81%E4%B8%9A%E6%9C%8D%E5%8A%A1%E6%80%BB%E7%BA%BF\n\n- Spring Integration:https://spring.io/projects/spring-integration\n\n- Mule ESB:https://www.mulesoft.com/resources/esb/what-mule-esb\n\n- Apache Camel:https://camel.apache.org/\n\n#### JMS\n\nJMS:https://www.oracle.com/java/technologies/java-message-service.html\n\nhttps://spring.io/guides/gs/messaging-jms/\n\n- Spring JMS is the Spring abstraction over the JMS API.\n- JMS is just an API; you need a physical broker to actually do messaging.\n- ActiveMQ is not a framework, it is an open-source JMS broker that supports the actual persistence and delivery of messages.\n- Spring JMS can be used with any JMS broker, including ActiveMQ. Each broker provides its own JMS API client jar.\n- RabbitMQ is not a native JMS broker; its native protocol is AMQP 0.9.1; it does, however, provide a JMS API client that can be used with Spring JMS, but Spring AMQP is the preferred library for talking to RabbitMQ because it provides much more functionality than is available over JMS.\n- There are lots of examples for using Spring JMS on the internet.\n- The simplest way to get started is with Spring Boot and `@JmsListener`.\n\n### 基本原理\n\n从网络通信的底层去看,通信要做的事情就是把流从一台计算机传输到另外一台计算机。使用传输协议和网络IO实现,传输协议比较知名的如 `TCP` 、`UDP` 等。\n\n`TCP` 和 `UDP` 都是在基于 `socket` 的概念上为某类应用场景扩展出来的传输层协议。\n\n网络 `IO` 主要由 `bio` 、`nio`、`aio`,所有的分布式都是基于这个原理实现的。\n\n### 什么是RPC\nrpc全称是 `remote procedure call` ,既远程过程调用。借助 `RPC` 可以做到像本地调用一样调用远程服务,是一种进程间的通信方式。\n\n`RPC` 不是一个具体的技术,而是指整个网络调用的过程。\n\n下面展示的是本地调用和远程调用的示例:\n\n例如有A服务器部署了一个应用,B服务器也部署了一个应用,现在A服务器上的应用想要调用B服务器上的应用的方法,由于,两个应用不在同一个服务器,因此不在同一个内存空间,无法实现直接调用,需要通过网络来表达调用的语义和传达调用的数据。\n\n\n\n\n\n### RPC架构\n\n一个完整的RPC架构包含四个完整的组件,分表是Client,Client Stub,Server和Server Stub。Stub可以理解为存根。\n\n* 客户端(Client),服务的调用方。\n* 客户端存根(Client Stub),存放服务端的地址消息,将客户端的请求打包成网络消息,通过网络远程发送给服务方。\n* 服务端(Server),真正的服务端提供者。\n* 服务端存根(Sever Stub),接收客户端发送过来的消息,将消息解包,并调用本地方法。\n\n\n\n\n\n\n\n1、客户端以本地方式调用服务\n\n2、客户端存根接收到调用之后,将方法参数组装成能进行网络传输的消息体,消息体序列化为二进制\n\n3、客户端通过`socket`将消息发送到服务端\n\n4、服务端存根接收到消息之后进行解码,将消息对象反序列化\n\n5、服务端存根根据解码结果调用本地服务\n\n6、服务处理\n\n7、本地服务执行并将结果返回给服务端存根\n\n8、服务端存根将返回结果打包成消息,将结果消息对象序列化\n\n9、服务端通过socket将消息发送到客户端\n\n10、客户端存根接收到消息并进行解码,将消息对象反序列化\n\n11、客户端得到最终结果\n\nRPC的目标是只保留1、6、11,将其他的细节全部封装起来。\n\n注意:不管是什么类型的数据,在输出过程中都要转换成二进制流,而接收方需要将二进制流恢复为对象。\n\nJava中常见的RPC框架有Hessian、gRPC、Dubbo等,核心模块都是通讯和序列化\n\nhttps://github.com/grpc/grpc-java\n\n### RMI\n\nJava的RMI指的是 `Remote Method Invocation`,一种实现远程过程调用(RPC)的API,能直接传输序列化后的Java对象。它的实现依赖于JVM,因此它能支撑一个JVM到另外一个JVM的调用。\n\n\n\n\n1、客户端从远程服务器的注册表中查询并获取远程对象的引用。\n\n2、桩对象与远程对象有相同的接口和方法列表,当客户端调用远程对象时候,实际上是由桩对象代理完成。\n\n3、远程引用层将桩的本地引用转换为服务器上对象的远程引用,再将调用层传递给传输层,由传输层通过TCP协议发起调用。\n\n4、在服务端,传输层监听入站链接,收到客户端的远程调用之后,将引用转发到上层的远程引用层;\n\n服务端的远程引用层将客户端发送的远程引用转换为本地虚拟机的引用,再将请求传递给骨架;\n\n骨架读取参数,将请求传递给服务器,由服务器进行实际的方法调用。\n\n5、如果远程方法调用之后有返回值,服务器将结果沿着 \"骨架->远程引用层->传输层\" 向下传递。\n\n6、客户端的传输层接收到返回值之后,又沿着 \"传输层->远程引用层->桩\" 向上传递,并最终将结果传递给客户端程序。\n\n### RMI实例需求分析\n\n1、服务端提供根据ID查询用户的方法\n\n2、客户端调用服务端方法,并返回用户对象\n\n3、要求使用RMI进行远程通讯\n\n#### 服务端实现\n\n```java\n/**\n * RMI服务端\n *\n * @name: RMIServer\n * @author: terwer\n * @date: 2022-03-06 02:01\n **/\npublic class RMIServer {\n public static void main(String[] args) {\n try {\n // 1.注册Registry实例,绑定端口\n Registry registry = LocateRegistry.createRegistry(9998);\n // 2.创建远程对象\n IUserService userService = new UserServiceImpl();\n // 3.将远程对象注册到RMI服务器(既服务端注册表)\n registry.rebind(\"userService\", userService);\n\n System.out.println(\"RMI服务端启动成功\");\n } catch (RemoteException e) {\n e.printStackTrace();\n }\n }\n}\n```\n\n#### 客户端实现\n\n```java\n/**\n * RMI客户端\n *\n * @name: RMIClient\n * @author: terwer\n * @date: 2022-03-06 19:25\n **/\npublic class RMIClient {\n public static void main(String[] args) throws RemoteException, NotBoundException {\n // 1、获取Registry实例\n Registry registry = LocateRegistry.getRegistry(\"127.0.0.1\", 9998);\n // 2、通过Registry查找远程对象\n IUserService userService = (IUserService) registry.lookup(\"userService\");\n User user = userService.getUserById(1);\n System.out.println(\"userName = \" + user.getName());\n }\n}\n```\n\n#### 效果预览\n\n\"image-20220306193226744\"\n\n\"image-20220306193244530\"\n\n## 基于Netty实现RPC框架\n\n`Dubbo` 底层使用 `Netty` 作为网络通讯框架,要求使用 `Netty` 实现一个简单的 `RPC` 框架,消费者和提供者约定协议和接口,消费者远程调用提供者的服务。\n\n1、创建一个接口,定义抽象方法,用于消费者和提供者之间的约定。\n\n2、创建一个提供者,该类需要监听消费者的请求,并按照约定返回数据。\n\n3、创建一个消费者,该类需要透明的调用自己不存在的方法,内部需要使用 `Netty` 进行数据通信。\n\n4、提供者与消费者传输数据使用json字符串格式。\n\n5、提供者使用 `Netty` 集成 `Spring Boot` 环境。\n\n案例:客户端调用服务端,利用ID查询User对象的方法\n\n### 需求分析\n\n\"image-20220306234352362\"\n\n### 具体实现\n\n需要分成三个子项目\n\n```bash\n.\n├── custom-rpc-api\n├── custom-rpc-consumer\n├── custom-rpc-provider\n└── pom.xml\n```\n\n#### 主项目\n\n主项目的 `pom.xml`\n\n```xml\n\n\n 4.0.0\n com.terewrgreen\n custom-rpc\n pom\n 1.0.0\n\n \n custom-rpc-api\n custom-rpc-provider\n custom-rpc-consumer\n \n\n \n org.springframework.boot\n spring-boot-starter-parent\n 2.6.3\n \n\n \n UTF-8\n 4.3.0\n \n\n \n \n \n io.netty\n netty-all\n \n \n \n com.alibaba\n fastjson\n 1.2.79\n \n \n \n org.projectlombok\n lombok\n \n \n\n```\n\n#### custom-rpc-api\n\npom.xml\n\n```xml\n\n\n \n custom-rpc\n com.terewrgreen\n 1.0.0\n \n 4.0.0\n\n custom-rpc-api\n\n custom-rpc-api\n http://www.terwergreen.com\n\n \n UTF-8\n 1.8\n 1.8\n \n\n \n \n junit\n junit\n 4.13.1\n test\n \n \n\n \n \n \n \n\n```\n\n\n\n#### custom-rpc-consumer\n\npom.xml\n\n```xml\n\n\n \n custom-rpc\n com.terewrgreen\n 1.0.0\n \n 4.0.0\n\n custom-rpc-consumer\n\n custom-rpc-consumer\n http://www.terwergreen.com\n\n \n UTF-8\n 1.8\n 1.8\n \n\n \n \n com.terewrgreen\n custom-rpc-api\n 1.0.0\n \n\n \n junit\n junit\n 4.13.1\n test\n \n \n\n \n \n \n \n\n```\n\nRpcClient\n\n```java\n/**\n * Rpc客户端\n * 1、连接netty服务端\n * 2、提供给调用者关闭资源的方法\n * 3、提供消息发送的方法\n *\n * @name: RpcClient\n * @author: terwer\n * @date: 2022-03-13 21:04\n **/\npublic class RpcClient {\n\n private NioEventLoopGroup group;\n private Channel channel;\n\n private String ip;\n private int port;\n\n private RpcClientHandler rpcClientHandler = new RpcClientHandler();\n private ExecutorService executorService = Executors.newCachedThreadPool();\n\n public RpcClient(String ip, int port) {\n this.ip = ip;\n this.port = port;\n initClient();\n }\n\n /**\n * 初始化客户端,连接netty服务端\n */\n public void initClient() {\n\n try {\n // 创建线程组\n group = new NioEventLoopGroup();\n // 创建启动助手\n Bootstrap bootstrap = new Bootstrap();\n bootstrap.group(group)\n .channel(NioSocketChannel.class)\n .option(ChannelOption.SO_KEEPALIVE, true)\n .option(ChannelOption.SO_TIMEOUT, 3000)\n .handler(new ChannelInitializer() {\n @Override\n protected void initChannel(SocketChannel channel) throws Exception {\n ChannelPipeline pipeline = channel.pipeline();\n // String 编解码器\n pipeline.addLast(new StringDecoder());\n pipeline.addLast(new StringEncoder());\n // 客户端处理类\n pipeline.addLast(rpcClientHandler);\n }\n });\n channel = bootstrap.connect(ip, port).sync().channel();\n System.out.println(\"===========客户端启动成功==========\");\n } catch (Exception e) {\n if (channel != null) {\n channel.close();\n System.out.println(\"客户端关闭channel\");\n }\n if (group != null) {\n group.shutdownGracefully();\n System.out.println(\"客户端关闭group\");\n }\n e.printStackTrace();\n }\n }\n\n public void close(){\n if (channel != null) {\n channel.close();\n System.out.println(\"外部调用客户端关闭channel\");\n }\n if (group != null) {\n group.shutdownGracefully();\n System.out.println(\"外部调用客户端关闭group\");\n }\n }\n\n public Object send(String msg) throws ExecutionException, InterruptedException {\n rpcClientHandler.setRequestMessage(msg);\n Future future = executorService.submit(rpcClientHandler);\n return future.get();\n }\n}\n```\n\nRpcClienthandler\n\n```java\n/**\n * 客户端处理类\n * 1、发送消息\n * 2、接收消息\n *\n * @name: RpcClientHandler\n * @author: terwer\n * @date: 2022-03-13 23:01\n **/\npublic class RpcClientHandler extends SimpleChannelInboundHandler implements Callable {\n\n private ChannelHandlerContext ctx;\n // 消息\n private String requestMessage;\n private String responseMessage;\n\n public String getRequestMessage() {\n return requestMessage;\n }\n\n public void setRequestMessage(String requestMessage) {\n this.requestMessage = requestMessage;\n }\n\n /**\n * 通道读取就绪事件\n *\n * @param channelHandlerContext\n * @param msg\n * @throws Exception\n */\n @Override\n protected synchronized void channelRead0(ChannelHandlerContext channelHandlerContext, Object msg) throws Exception {\n responseMessage = (String) msg;\n // 唤醒等待线程\n notify();\n }\n\n /**\n * 通道就绪事件\n *\n * @param ctx\n * @throws Exception\n */\n @Override\n public void channelActive(ChannelHandlerContext ctx) throws Exception {\n this.ctx = ctx;\n }\n\n @Override\n public synchronized Object call() throws Exception {\n // 消息发送\n ctx.writeAndFlush(requestMessage);\n // 线程等待\n wait();\n return responseMessage;\n }\n}\n```\n\nRpcClientProxy\n\n```java\n/**\n * 客户端代理类,创建代理对象\n * 1、封装request请求对象\n * 2、创建RpcClient对象\n * 3、发送消息\n * 4、返回结果\n *\n * @name: RpcClientProxy\n * @author: terwer\n * @date: 2022-03-13 23:45\n **/\npublic class RpcClientProxy {\n public static Object createProxy(Class serviceClass) {\n return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[]{serviceClass}, new InvocationHandler() {\n @Override\n public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {\n // 1、封装request请求对象\n RpcRequest rpcRequest = new RpcRequest();\n rpcRequest.setRequestId(UUID.randomUUID().toString());\n rpcRequest.setClassName(method.getDeclaringClass().getName());\n rpcRequest.setMethodName(method.getName());\n rpcRequest.setParameterTypes(method.getParameterTypes());\n rpcRequest.setParameters(args);\n\n // 2、创建RpcClient对象\n RpcClient rpcClient = new RpcClient(\"127.0.0.1\", 9999);\n\n try {\n // 3、发送消息\n Object responseMessage = rpcClient.send(JSON.toJSONString(rpcRequest));\n\n // 4、返回结果\n RpcResponse response = JSON.parseObject(responseMessage.toString(), RpcResponse.class);\n if (response.getError() != null) {\n throw new RuntimeException(response.getError());\n }\n Object result = response.getResult();\n Object object = JSON.parseObject(result.toString(), method.getReturnType());\n return object;\n } catch (Exception e) {\n throw e;\n } finally {\n rpcClient.close();\n }\n\n\n }\n });\n }\n}\n```\n\nClientBoosStrap\n\n```java\n/**\n * 客户端启动类\n *\n * @name: ClientBootStrap\n * @author: terwer\n * @date: 2022-03-14 00:00\n **/\npublic class ClientBootStrap {\n public static void main(String[] args) {\n IUSerService userService = (IUSerService) RpcClientProxy.createProxy(IUSerService.class);\n User user = userService.getById(1);\n System.out.println(user);\n }\n}\n```\n\n\n\n#### custom-rpc-provider\n\npom.xml\n\n```xml\n\n\n \n custom-rpc\n com.terewrgreen\n 1.0.0\n \n 4.0.0\n\n custom-rpc-provider\n\n custom-rpc-provider\n http://www.terwergreen.com\n\n \n UTF-8\n 1.8\n 1.8\n \n\n \n \n com.terewrgreen\n custom-rpc-api\n 1.0.0\n \n \n \n org.springframework\n spring-context\n \n \n org.springframework.boot\n spring-boot-autoconfigure\n \n\n \n junit\n junit\n 4.13.1\n test\n \n \n\n \n \n \n \n\n```\n\n\n\nUserServiceImpl\n\n```java\n/**\n * 用户服务实现类\n *\n * @name: UserServiceImpl\n * @author: terwer\n * @date: 2022-03-09 23:34\n **/\n@RpcService\n@Service\npublic class UserServiceImpl implements IUSerService {\n Map userMap = new HashMap<>();\n\n @Override\n public User getById(int id) {\n User user = new User();\n user.setId(1);\n user.setName(\"唐有炜\");\n userMap.put(user.getId(), user);\n\n User user2 = new User();\n user2.setId(2);\n user2.setName(\"张三\");\n userMap.put(user2.getId(), user2);\n\n return userMap.get(id);\n }\n}\n```\n\nRpcServer\n\n```java\n/**\n * 对外服务\n *\n * @name: RpcServer\n * @author: terwer\n * @date: 2022-03-09 23:53\n **/\n@Service\npublic class RpcServer implements DisposableBean {\n private NioEventLoopGroup bossGroup;\n private NioEventLoopGroup workerGroup;\n\n @Autowired\n private RpcServerHandler rpcServerHandler;\n\n public void startServer(String ip, int port) {\n try {\n // 1、创建线程组\n bossGroup = new NioEventLoopGroup(1);\n workerGroup = new NioEventLoopGroup();\n\n // 2、创建服务端启动助手\n ServerBootstrap serverBootstrap = new ServerBootstrap();\n\n // 3、设置参数\n serverBootstrap.group(bossGroup, workerGroup)\n .channel(NioServerSocketChannel.class)\n .childHandler(new ChannelInitializer() {\n @Override\n protected void initChannel(SocketChannel channel) throws Exception {\n ChannelPipeline pipeline = channel.pipeline();\n // 添加String的编解码器\n pipeline.addLast(new StringDecoder());\n pipeline.addLast(new StringEncoder());\n // 业务处理类\n pipeline.addLast(rpcServerHandler);\n }\n });\n\n // 4、绑定端口\n ChannelFuture sync = serverBootstrap.bind(ip, port).sync();\n System.out.println(\"===========服务端启动成功=============\");\n sync.channel().closeFuture().sync();\n } catch (InterruptedException e) {\n e.printStackTrace();\n } finally {\n if (bossGroup != null) {\n bossGroup.shutdownGracefully();\n System.out.println(\"finally bossGroup成功关闭\");\n }\n if (workerGroup != null) {\n workerGroup.shutdownGracefully();\n System.out.println(\"finally workerGroup成功关闭\");\n }\n }\n }\n\n @Override\n public void destroy() throws Exception {\n if (bossGroup != null) {\n bossGroup.shutdownGracefully();\n System.out.println(\"destroy bossGroup成功关闭\");\n }\n if (workerGroup != null) {\n workerGroup.shutdownGracefully();\n System.out.println(\"destroy workerGroup成功关闭\");\n }\n }\n}\n```\n\nRpcServerHandler\n\n```java\n/**\n * 服务端处理类\n *

    \n * 1、将标有@RpcService注解的类进行缓存\n * 2、接收客户端请求\n * 3、根据传过来的beanName在缓存中查找对应的bean\n * 4、解析请求中的方法名、参数类型、参数信息\n *\n * @name: RpcServerHandler\n * @author: terwer\n * @date: 2022-03-10 00:22\n **/\n@Component\n@ChannelHandler.Sharable\npublic class RpcServerHandler extends SimpleChannelInboundHandler implements ApplicationContextAware {\n private static final Map SERVICE_INSTANCE_MAP = new ConcurrentHashMap();\n\n /**\n * 1、将标有@RpcService注解的类进行缓存\n *\n * @param applicationContext\n * @throws BeansException\n */\n @Override\n public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {\n Map serviceMap = applicationContext.getBeansWithAnnotation(RpcService.class);\n if (serviceMap != null && serviceMap.size() > 0) {\n Set> entries = serviceMap.entrySet();\n for (Map.Entry entry : entries) {\n Object serviceBean = entry.getValue();\n if (serviceBean.getClass().getInterfaces().length == 0) {\n throw new RuntimeException(\"服务必须实现接口\");\n }\n\n // 默认取第一个接口作为名称\n SERVICE_INSTANCE_MAP.put(serviceBean.getClass().getInterfaces()[0].getName(), serviceBean);\n }\n\n }\n }\n\n /**\n * 通道读取就绪事件\n *\n * @param channelHandlerContext\n * @param s\n * @throws Exception\n */\n @Override\n protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {\n // 接收客户端请求,转换成RpcReuest\n RpcRequest rpcRequest = JSON.parseObject(msg, RpcRequest.class);\n RpcResponse rpcResponse = new RpcResponse();\n rpcResponse.setRequestId(rpcRequest.getRequestId());\n\n try {\n Object result = handler(rpcRequest);\n rpcResponse.setResult(result);\n } catch (Exception e) {\n rpcResponse.setError(e.getMessage());\n e.printStackTrace();\n }\n\n ctx.writeAndFlush(JSON.toJSONString(rpcResponse));\n }\n\n /**\n * 业务逻辑处理方法\n *\n * @param rpcRequest\n * @return\n */\n private Object handler(RpcRequest rpcRequest) throws InvocationTargetException {\n // 根据传过来的beanName在缓存中查找对应的bean\n Object serviceBean = SERVICE_INSTANCE_MAP.get(rpcRequest.getClassName());\n if(null == serviceBean){\n throw new RuntimeException(\"根据beanName找不到服务\"+rpcRequest.getClassName());\n }\n\n // 解析请求中的方法名、参数类型、参数信息\n Class beanClass = serviceBean.getClass();\n String methodName = rpcRequest.getMethodName();\n Class[] parameterTypes = rpcRequest.getParameterTypes();\n Object[] parameters = rpcRequest.getParameters();\n\n // 反射调用\n FastClass fastClass = FastClass.create(beanClass);\n FastMethod fastMethod = fastClass.getMethod(methodName, parameterTypes);\n Object result = fastMethod.invoke(serviceBean, parameters);\n\n return result;\n }\n}\n```\n\nServerBootdtrapApplication\n\n```java\n/**\n * 启动类\n *\n * @name: ServerBootstrapApplication\n * @author: terwer\n * @date: 2022-03-09 23:46\n **/\n@SpringBootApplication\npublic class ServerBootstrapApplication implements CommandLineRunner {\n @Autowired\n private RpcServer rpcServer;\n\n public static void main(String[] args) {\n SpringApplication.run(ServerBootstrapApplication.class, args);\n }\n\n @Override\n public void run(String... args) throws Exception {\n new Thread(new Runnable() {\n @Override\n public void run() {\n rpcServer.startServer(\"127.0.0.1\", 9999);\n }\n }).start();\n }\n}\n```\n\n\n\n运行效果\n\n\"image-20220314001934218\"\n\n\"image-20220314002004686\"\n\n错误解决\n\n```\ncom.terewrgreen.rpc.provider.handler.RpcServerHandler is not a @Sharable handler, so can\'t be added or removed multiple times.\n```\n\n加上 `@ChannelHandler.Sharable` 注解即可。\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7955, 'jvm-he-xin-zhi-shi-dian-can-kao-shen-ru-li-jiejvm', 'JVM核心知识点,参考深入理解JVM', '2022-03-07 22:44:16', '2022-03-08 23:10:39', '\n\n类加载器、运行时方法区、垃圾收集器的关系\n\n![m](https://raw.githubusercontent.com/terwer/upload/main/img/20220308150300.png)\n\n# 运行时数据区\nhttps://www.cnblogs.com/wuzhenzhao/p/12346515.html\n\n![image-20220308220533363](https://raw.githubusercontent.com/terwer/upload/main/img/20220308220546.png)\n\n## HotSpot经典的内存模型\n\n### JDK1.7以前\n\n![image-20220308151828028](https://raw.githubusercontent.com/terwer/upload/main/img/20220308152125.png)\n\n### JDK1.8以后\n\n![img](https://raw.githubusercontent.com/terwer/upload/main/img/20220308145602.png)\n\n备注:\n\n- JDK1.8以前叫方法区,JDK1.8以后叫元空间。详细参考\n\n [JVM学习——元空间(Metaspace)](https://www.jianshu.com/p/a6f19189ec62)\n\n [面试官 | JVM 为什么使用元空间替换了永久代?](https://zhuanlan.zhihu.com/p/111809384)\n\n- `CodeCache`在JVM官方文档中被归于元空间,而在阿里的官方文档中被单独摘了出来。\n\n# 垃圾回收机制与内存分配\n\nhttps://www.cnblogs.com/wuzhenzhao/p/12457908.html\n\nhttps://www.cnblogs.com/aspirant/p/8662690.html\n\n[CMS和G1 的区别]() \n\n# 类加载机制\n\nhttps://segmentfault.com/a/1190000037574626\n\n## 类文件结构\n\n## 加载链接初始化\n\n## 字节码执行引擎\n\n# 程序编译与代码优化\n\nhttps://mbd.baidu.com/ug_share/mbox/4a81af9963/share?tk=77db9eeadcf9964bc8f294bc3ff87089&share_url=https%3A%2F%2Fyebd1h.smartapps.cn%2Fpages%2Fblog%2Findex%3FblogId%3D106164810%26_swebfr%3D1%26_swebFromHost%3Dbaiduboxapp\n\n## 前端编译\n\n## 后端编译\n\n怎么让面试官觉得你确实做过JVM调优而不是觉得只是背了几篇八股文,换句话说,怎么让自己面试JVM的时候感觉有底气?\n\n调优实现流程、问题定位?', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7956, '', '', '2022-03-11 03:03:38', '2022-03-11 11:03:38', '好的产品应该是不需要教用户怎么去用,也就说,不要增加不必要的步骤或者附加信息,让用户去猜。如果,用户用这个功能的学习成本变得很高,那么这个功能就是失败的。', 1, 0, NULL, NULL, 'publish', 'essay', 1, 0); +INSERT INTO `posts` VALUES (7957, 'jdbc-de-wen-ti-fen-xi', 'JDBC的问题分析', '2022-03-05 09:33:01', '2022-03-14 02:34:22', '\n# 自定义RPC框架\n> 2022/03/06 校对完成 \n>\n> 文章更新历史\n> \n> 2022/03/16 初稿。\n>\n> 原文地址:[http://www.terwergreen.com/post/jdbc-de-wen-ti-fen-xi.html](http://www.terwergreen.com/post/jdbc-de-wen-ti-fen-xi.html)\n# 核心实现\n\n```\npackage test;\n\nimport java.sql.Connection;\nimport java.sql.DriverManager;\nimport java.sql.PreparedStatement;\nimport java.sql.ResultSet;\n\n/**\n * @author terwer\n * @Description\n * @create 2021-11-30 23:18\n */\npublic class Main {\n public static void main(String[] args) {\n Connection connection = null;\n PreparedStatement preparedStatement = null;\n ResultSet resultSet = null;\n try {\n // 1、加载数据库驱动\n Class.forName(\"com.mysql.jdbc.Driver\");\n // 2、获取数据库链接\n connection = DriverManager.getConnection(\"jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8&useSSL=false\", \"root\", \"123456\");\n\n // 3、定义sql语句\n String sql = \"select * from user where username = ?\";\n // 4、获取预处理对象\n preparedStatement = connection.prepareStatement(sql);\n // 5、设置参数\n preparedStatement.setString(1, \"hp\");\n // 6、拿到查询的数据库结果\n resultSet = preparedStatement.executeQuery();\n\n while (resultSet.next()) {\n int id = resultSet.getInt(\"id\");\n String username = resultSet.getString(\"username\");\n\n User user = new User();\n user.setId(id);\n user.setUsername(username);\n\n System.out.println(\"user = \" + user.toString());\n }\n\n // JDBC问题分析\n // 1、数据库链接信息等存在硬编码 解决:配置文件\n // 2、频繁创建释放数据库链接 解决:连接池(c3p0、druid)\n\n // 查询过程问题分析\n // 1、sql语句、参数、结果集存在硬编码 解决:配置文件\n\n // 结果集问题分析\n // 1、需要手动封装结果集 解决:反射进行对象映射、内省\n\n } catch (Exception e) {\n e.printStackTrace();\n } finally {\n System.out.println(\"释放资源\");\n }\n }\n}\n\n```\n\n1.1 问题分析\nJDBC问题总结:\n原始jdbc开发存在的问题如下:\n1、 数据库连接创建、释放频繁造成系统资源浪费,从而影响系统性能。\n2、 Sql语句在代码中硬编码,造成代码不易维护,实际应用中sql变化的可能较大,sql变动需要改变 java代码。\n3、 使用preparedStatement向占有位符号传参数存在硬编码,因为sql语句的where条件不一定,可能 多也可能少,修改sql还要修改代码,系统不易维护。\n4、 对结果集解析存在硬编码(查询列名),sql变化导致解析代码变化,系统不易维护,如果能将数据库记录封装成 pojo对象解析比较方便\n\n1.2 问题解决思路\n1使用数据库连接池初始化连接资源\n2将sql语句抽取到xml配置文件中\n3使用反射、内省等底层技术,自动将实体与表进行属性与字段的自动映射\n\n# mysql驱动链接\n\n[https://files.cnblogs.com/files/tangyouwei/mysql-connector-java-5.1.49.jar.zip](https://files.cnblogs.com/files/tangyouwei/mysql-connector-java-5.1.49.jar.zip)\n\n# 源码\n\nGitee版\n\n[https://gitee.com/youweics/senior-java-engineer-road/blob/master/p7-skill/framework/mybatis/jdbc-simple/src/main/java/com/terwergreen/App.java](https://gitee.com/youweics/senior-java-engineer-road/blob/master/p7-skill/framework/mybatis/jdbc-simple/src/main/java/com/terwergreen/App.java)\n\nGithub版\n\n[https://github.com/terwer/senior-java-engineer-road/blob/master/p7-skill/framework/mybatis/jdbc-simple/src/main/java/com/terwergreen/App.java](https://github.com/terwer/senior-java-engineer-road/blob/master/p7-skill/framework/mybatis/jdbc-simple/src/main/java/com/terwergreen/App.java)', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7958, 'idea-zi-ding-yimaven-archetype', 'IDEA自定义Maven的archetype', '2022-03-03 04:32:00', '2022-03-27 13:42:33', '\n> 2022/03/14 验证通过 \n>\n> 文章更新历史\n> \n> 2022/03/03 初稿。\n>\n> 原文地址:[http://www.terwergreen.com/post/idea-zi-ding-yimaven-archetype.html](http://www.terwergreen.com/post/idea-zi-ding-yimaven-archetype.html)\n# 为什么要自定义archetype\n\n在创建Maven的项目时我们发现了一个很不方便的问题,就是每次创建Maven的工程的时候,都需要选择一个骨架,但是每个骨架都需要删除一部分东西才行,在平时开发中,如果是分布式项目,有可能会频繁创建子项目,每次都要删除不要的文件然后拷贝我们要的文件,例如弹簧配置,web.xml中配置等。这样做不仅会浪费大量时间,拷贝和删除文件也容易导致错误的发生,比如漏拷某文件。\n\n# Archetype maven 项目的组成\n\n一个典型的Archetype Maven项目主要包括如下几个部分:\n\n* pom.xml:Archetype自身的POM。\n* src/main/resources/archetype-resources/pom.xml:基于该Archetype生成项目的POM原型。\n* src/main/resources/META-INF/maven/archetype-metadata.xml:Archetype的描述符文件。\n* src/main/resources/archetype-resources/**:其他需要包含在Archetype中的内容。\n\n# 创建自己的骨架结构\n\n要创建Maven的模板,首先你要创建一个Maven的项目,然后再以这个项目作为模板。\n\n## 创建maven工程\n首先创建一个Maven的工程,名字叫maven-template-java-simple\n\n选择骨架 \n\n\n\n## 骨架创建\n\n在maven-template-java-simple根目录执行 \n\n```\nmvn archetype:create-from-project\n```\n\n报错解决\n\n```\nmvn archetype:create-from-project报错The specified user settings file does not exist\n```\n\nhttps://www.cnblogs.com/chmod/p/15489910.html\n\n执行完毕之后,会出现一个编译之后新的maven工程(target文件夹),如下图:\n\n\n\n## 骨架安装\n安装对应骨架项目\n\n先进入骨架项目的pom文件目录:\n\n```\ncd target/generated-sources/archetype\n```\n\n执行安装:\n\n```\nmvn clean install\n```\n\n我们的骨架项目坐标如下:\n\n```\ncom.terwergreen\nmaven-template-java-simple-archetype\n1.0.0\nmaven-archetype\n```\n\n至此,骨架项目安装成功。\n\n# 使用自己创建的自定义骨架\n\n创建新的Maven工程,选择自定义骨架\n\n## 添加骨架\n创建新的maven工程,选择Add Archetype,填写刚才添加的骨架工程坐标,点击OK,这是会生成一个新的骨架选项。\n\n```\ngroupId com.terwergreen\nartifactId maven-template-java-simple-archetype\nversion 1.0.0\n```\n\n\n\n选中新创建的骨架,点击下一步创建新的Maven的项目如下,这是新建的测试项目:\n\n\n\n\n\n\n\n\n\n以后再创建类似的Maven的项目时,就可以快速新建的Maven项目而不用改来改去了。是不是很方便呢?\n\nPS:删除自定义archetype\n\n```\ncd /Users/terwer/Library/Caches/JetBrains/IntelliJIdea2021.3/Maven/Indices\n```\n\n然后编辑 UserArchetypes.xml 文件即可。注意:修改文件之后需要重启IDEA。\n\n', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7959, 'zi-ding-yi-chi-jiu-ceng-kuang-jia', '自定义持久层框架', '2022-03-13 10:01:11', '2022-03-27 13:36:37', '\n> 2022/03/14 校对完成 \n>\n> 文章更新历史\n> \n> 2022/03/14 初稿。\n>\n> 原文地址:[http://www.terwergreen.com/post/zi-ding-yi-chi-jiu-ceng-kuang-jia.html](http://www.terwergreen.com/post/zi-ding-yi-chi-jiu-ceng-kuang-jia.html)\n# 核心要点\n\n1、解析配置文件\n\n1.1 数据库配置信息\n\n1.2 sql的封装\n\n2、构建SqlSessionFactory,注意这里的openSession方法\n\n3、拿到SqlSesion\n\n3.1 定义SqlSession基本方法\n\n3.2 封装具体的执行逻辑,Executor\n\nExecute的query方法就对应jdbc操作\n\n3.3 优化,使用JDK动态代理避免statementId的硬编码\n\n4、将SqlSession的操作封装到DAO层\n\n# 自定义持久层框架设计思路\n\n## 使用端(项目)\n\n- 引入自定义持久层框架的jar包\n\n- 提供两部分配置信息\n\n - 数据库配置信息\n\n - sql配置信息:sql语句、参数类型、返回值类型\n\n- 使用配置文件来提供这两部分配置信息:\n\n(1)`sqlMapConfig.xml` :存放数据库配置信息,存放 `mapper.xml` 的全路径\n\n(2)`mapper.xml` :存放sql配置信息\n\n## 自定义持久层框架本身(工程)\n\n本质是对JDBC代码进行封装\n\n- 加载配置文件\n\n 根据配置文件的路径记载成字节输入流,存储到内存中\n\n 创建Resources类\n\n 方法:InputStream getResourceAsStream(String path)\n\n- 创建两个JavaBean(容器对象):存放的是配置文件解析出来的内容\n\n Configuration:核心配置类,存放 `sqlMapConfig.xml` 解析出来的内容\n\n MappedStatement:映射配置类,存放 `mapper.xml` 解析出来的内容\n\n- 解析配置文件:dom4j\n\n 创建类:sqlSessionFactoryBuilder类,方法 build(InputStream in)\n\n 1、使用dom4j解析配置文件,将解析出来的内容封装到威器对象中\n\n 2、创建SqlSessionFactory对象,生产SqlSession(会话对象),工厂模式\n\n- 创建SqlSessionFactory以及实现类DefaultSqlSessionFactory\n\n openSession():生产SqlSession\n\n - 创建SqlSession接口及实现类DefaultSqlSession\n\n 定义对数据库的CRUD操作:selectList()\n\n ​ selectOne()\n\n ​ update()\n\n ​ delete()\n\n - 创建Executor实现类以及实现类SimpleExecutor \n\n query(Configuration configuration, MappedStatement mappedStatement, Object... params):执行JDBC代码\n\n# 代码实现\n\n### 项目结构\n\n```\n.\n├── IPersistence\n│   ├── IPersistence.iml\n│   ├── pom.xml\n│   └── src\n└── IPersistence_test\n ├── IPersistence_test.iml\n ├── pom.xml\n ├── src\n └── target\n```\n\n- sqlMapperConfig.xml配置文件\n\n```xml\n\n \n \n \n \n \n \n \n\n \n \n\n```\n\n- UserMapper.xml配置文件\n\n```xml\n\n \n \n \n\n```\n\n- 读取资源处理,Resources类\n\n```java\n/**\n * 资源处理类\n *\n * @name: Resource\n * @author: terwer\n * @date: 2022-03-14 12:57\n **/\npublic class Resources {\n /**\n * 根据配置文件的路径,将配置文件加载成字节输入流,存储到内存中\n *\n * @param path\n * @return\n */\n public static InputStream getResourceAsStream(String path) {\n InputStream inputStream = Resources.class.getClassLoader().getResourceAsStream(path);\n return inputStream;\n }\n}\n```\n\n- SqlSessionFactoryBuider工厂构建对象\n\n```java\n/**\n * 工厂构建对象\n *\n * @name: SqlSessionFactoryBuilder\n * @author: terwer\n * @date: 2022-03-14 15:18\n **/\npublic class SqlSessionFactoryBuilder {\n public SqlSessionFactory build(InputStream in) throws DocumentException, PropertyVetoException {\n // 1、解析配置文件,将解析出来的内容封装到Configuration中\n XmlConfigBuilder xmlConfigBuilder = new XmlConfigBuilder();\n Configuration configuration = xmlConfigBuilder.parse(in);\n\n // 2、创建SqlSessionFactory对象\n DefaultSqlSessionFactory sqlSessionFactory = new DefaultSqlSessionFactory(configuration);\n return sqlSessionFactory;\n }\n\n}\n```\n\n- 配置文件解析\n\n```java\n/**\n * @name: XmlConfigBuilder\n * @author: terwer\n * @date: 2022-03-14 15:40\n **/\npublic class XmlConfigBuilder {\n\n private Configuration configuration;\n\n public XmlConfigBuilder() {\n configuration = new Configuration();\n }\n\n /**\n * 使用dom4j将配置文件进行解析,封装Configuration\n *\n * @param in\n * @return\n */\n public Configuration parse(InputStream in) throws DocumentException, PropertyVetoException {\n Document document = new SAXReader().read(in);\n // \n Element rootElement = document.getRootElement();\n\n List list = rootElement.selectNodes(\"//property\");\n Properties properties = new Properties();\n for (Element element : list) {\n String name = element.attributeValue(\"name\");\n String value = element.attributeValue(\"value\");\n\n properties.setProperty(name, value);\n }\n\n ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();\n comboPooledDataSource.setDriverClass(properties.getProperty(\"driverClass\"));\n comboPooledDataSource.setJdbcUrl(properties.getProperty(\"jdbcUrl\"));\n comboPooledDataSource.setUser(properties.getProperty(\"username\"));\n comboPooledDataSource.setPassword(properties.getProperty(\"password\"));\n\n configuration.setDataSource(comboPooledDataSource);\n\n // mapper.xml解析,拿到路径,加载成字节输入流,进行解析\n List mapperList= rootElement.selectNodes(\"//mapper\");\n // \n for (Element element : mapperList) {\n String mapperPath = element.attributeValue(\"resource\");\n InputStream resourceAsStream = Resources.getResourceAsStream(mapperPath);\n\n XmlMapperBuilder xmlMapperBuilder = new XmlMapperBuilder(configuration);\n xmlMapperBuilder.parse(resourceAsStream);\n }\n\n return configuration;\n }\n}\n```\n\n- mapper映射文件解析\n\n```java\n/**\n * mapper解析器\n *\n * @name: XmlMapperBuilder\n * @author: terwer\n * @date: 2022-03-14 16:16\n **/\npublic class XmlMapperBuilder {\n private Configuration configuration;\n\n public XmlMapperBuilder(Configuration configuration) {\n this.configuration = configuration;\n }\n\n public void parse(InputStream in) throws DocumentException {\n Document document = new SAXReader().read(in);\n\n // \n Element rootElement = document.getRootElement();\n String namespace = rootElement.attributeValue(\"namespace\");\n\n List list = rootElement.selectNodes(\"//select\");\n for (Element element : list) {\n String id = element.attributeValue(\"id\");\n String resultType = element.attributeValue(\"resultType\");\n String parameterType = element.attributeValue(\"parameterType\");\n\n String sqlText = element.getTextTrim();\n\n MappedStatement mappedStatement = new MappedStatement();\n mappedStatement.setStatementId(id);\n mappedStatement.setResultType(resultType);\n mappedStatement.setParameterType(parameterType);\n mappedStatement.setSql(sqlText);\n\n Map mappedStatementMap = configuration.getMappedStatementMap();\n String statementId = namespace + \".\" + id;\n mappedStatementMap.put(statementId, mappedStatement);\n }\n }\n}\n```\n\n- SqlSession的具体实现\n\n```java\n/**\n * @name: DefaultSqlSession\n * @author: terwer\n * @date: 2022-03-14 16:36\n **/\npublic class DefaultSqlSession implements SqlSession {\n private Configuration configuration;\n\n public DefaultSqlSession(Configuration configuration) {\n this.configuration = configuration;\n }\n\n @Override\n public List selectList(String statementId, Object... params) throws Exception {\n SimpleExecutor simpleExecutor = new SimpleExecutor();\n MappedStatement mappedStatement = configuration.getMappedStatementMap().get(statementId);\n return simpleExecutor.query(configuration, mappedStatement, params);\n }\n\n @Override\n public T selectOne(String statementId, Object... params) throws Exception {\n List objects = selectList(statementId, params);\n if (objects.size() == 1) {\n return (T) objects.get(0);\n } else {\n throw new RuntimeException(\"查询数据为空或者返回结果过多\");\n }\n }\n}\n```\n\n- 核心执行引擎Executor的实现\n\n```java\n/**\n * 执行器的实现\n *\n * @name: SimpleExecutor\n * @author: terwer\n * @date: 2022-03-14 16:53\n **/\npublic class SimpleExecutor implements Executor {\n @Override\n public List query(Configuration configuration, MappedStatement mappedStatement, Object... params) throws Exception {\n // 注册驱动,获取链接\n Connection connection = configuration.getDataSource().getConnection();\n\n // 获取sql语句\n // 获取的sql\n // select * from user where id = #{id} and username = #{username}\n // 转换后的sql\n // select * from user where id = ? and username = ?\n String sql = mappedStatement.getSql();\n\n // 转换sql语句\n BoundSql boundSql = getBoundSql(sql);\n\n // 获取预处理对象\n PreparedStatement preparedStatement = connection.prepareStatement(boundSql.getSqlText());\n\n // 设置参数\n // 参数全路径\n String parameterType = mappedStatement.getParameterType();\n Class parameterClass = getClassType(parameterType);\n\n List parameterMappingList = boundSql.getParameterMappingList();\n for (int i = 0; i < parameterMappingList.size(); i++) {\n ParameterMapping parameterMapping = parameterMappingList.get(i);\n String content = parameterMapping.getContent();\n\n Field field = parameterClass.getDeclaredField(content);\n field.setAccessible(true);\n Object value = field.get(params[0]);\n\n preparedStatement.setObject(i + 1, value);\n }\n\n // 执行sql\n ResultSet resultSet = preparedStatement.executeQuery();\n String returnType = mappedStatement.getResultType();\n Class resultTypeClass = getClassType(returnType);\n Object o = resultTypeClass.newInstance();\n ArrayList objects = new ArrayList<>();\n\n // 封装返回结果集\n while (resultSet.next()) {\n ResultSetMetaData metaData = resultSet.getMetaData();\n for (int i = 1; i <= metaData.getColumnCount(); i++) {\n String columnName = metaData.getColumnName(i);\n // 获取字段值\n Object value = resultSet.getObject(columnName);\n\n // 使用反射或者内省,根据数据库表和实体的对应关系完成封装\n PropertyDescriptor propertyDescriptor = new PropertyDescriptor(columnName, resultTypeClass);\n Method writeMethod = propertyDescriptor.getWriteMethod();\n writeMethod.invoke(o, value);\n }\n objects.add(o);\n }\n\n return (List) objects;\n }\n\n private Class getClassType(String parameterType) throws ClassNotFoundException {\n if (parameterType != null) {\n Class aClass = Class.forName(parameterType);\n return aClass;\n }\n return null;\n }\n\n /**\n * 1、将#{}使用?代替\n * 2、解析出#{}的值进行存储\n *\n * @param sql\n * @return\n */\n private BoundSql getBoundSql(String sql) {\n // 标记处理类,配合标记解析器完成对占位符的解析\n ParameterMappingTokenHandler tokenHandler = new ParameterMappingTokenHandler();\n GenericTokenParser genericTokenParser = new GenericTokenParser(\"#{\", \"}\", tokenHandler);\n\n // 解析后的sql\n String parseSql = genericTokenParser.parse(sql);\n // 解析的参数名称\n List parameterMappings = tokenHandler.getParameterMappings();\n\n BoundSql boundSql = new BoundSql(parseSql, parameterMappings);\n\n return boundSql;\n }\n}\n```\n\n运行效果\n\n\"image-20220314182811682\"\n\n### 问题修复\n\n1、selectList打印的全部是同一个值\n\n```\n/Library/Java/JavaVirtualMachines/jdk1.8.0_291.jdk/Contents/Home/bin/java -... com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit4 com.terwergreen.test.IPersistenceTest,test2\nConnected to the target VM, address: \'127.0.0.1:50317\', transport: \'socket\'\nlog4j:WARN No appenders could be found for logger (com.mchange.v2.log.MLog).\nlog4j:WARN Please initialize the log4j system properly.\nUser{id=5, username=\'dali\'}\nUser{id=5, username=\'dali\'}\nUser{id=5, username=\'dali\'}\nUser{id=5, username=\'dali\'}\nDisconnected from the target VM, address: \'127.0.0.1:50317\', transport: \'socket\'\n\nProcess finished with exit code 0\n\n```\n\n修正方案\n\n\"image-20220314190526971\"\n\n修正后\n\n```\n/Library/Java/JavaVirtualMachines/jdk1.8.0_291.jdk/Contents/Home/bin/java -... com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit4 com.terwergreen.test.IPersistenceTest,test2\nConnected to the target VM, address: \'127.0.0.1:50820\', transport: \'socket\'\nlog4j:WARN No appenders could be found for logger (com.mchange.v2.log.MLog).\nlog4j:WARN Please initialize the log4j system properly.\nUser{id=1, username=\'tyw\'}\nUser{id=2, username=\'张月\'}\nUser{id=4, username=\'haha\'}\nUser{id=5, username=\'dali\'}\nDisconnected from the target VM, address: \'127.0.0.1:50820\', transport: \'socket\'\n\nProcess finished with exit code 0\n```\n\n### 代码仓库\n\nGitee版\n\nhttps://gitee.com/youweics/senior-java-engineer-road/tree/master/p7-skill/framework/mybatis/custom-persistence\n\nGithub版\n\nhttps://github.com/terwer/senior-java-engineer-road/tree/master/p7-skill/framework/mybatis/custom-persistence\n\n# 自定义持久层框架的优化\n\n问题分析\n\n1、Dao层使用持久层框架,存在代码重复,整个操作过程模板重复(加载配置文件、创建SqlSessionFactory、生产SqlSession)\n\n2、存在硬编码(statementId)\n\n解决思路\n\n### getMapper+动态代理方式优化\n\n使用代理模式生成Dao层接口的实现类\n\n\"image-20220314210007908\"\n\n\"image-20220314212415390\"\n\n### 优化版代码\n\n[https://gitee.com/youweics/senior-java-engineer-road/tree/mybatis-proxy/p7-skill/framework/mybatis/custom-persistence](https://gitee.com/youweics/senior-java-engineer-road/tree/mybatis-proxy/p7-skill/framework/mybatis/custom-persistence)\n\n[https://github.com/terwer/senior-java-engineer-road/tree/mybatis-proxy/p7-skill/framework/mybatis/custom-persistence](https://github.com/terwer/senior-java-engineer-road/tree/mybatis-proxy/p7-skill/framework/mybatis/custom-persistence)\n\n### 默认实现方式\n\n[https://gitee.com/youweics/senior-java-engineer-road/tree/mybatis-normal/p7-skill/framework/mybatis/custom-persistence](https://gitee.com/youweics/senior-java-engineer-road/tree/mybatis-normal/p7-skill/framework/mybatis/custom-persistence)\n\n[https://github.com/terwer/senior-java-engineer-road/tree/mybatis-normal/p7-skill/framework/mybatis/custom-persistence](https://github.com/terwer/senior-java-engineer-road/tree/mybatis-normal/p7-skill/framework/mybatis/custom-persistence)\n\n', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7960, 'mac-demysql-pei-zhi', 'Mac的MySQL配置', '2022-03-19 00:26:19', '2022-03-19 16:33:25', '\n> 2022/03/19 验证通过 \n>\n> 文章更新历史\n> \n> 2022/03/14 初稿。\n>\n> 原文地址:[http://www.terwergreen.com/post/mac-demysql-pei-zhi.html](http://www.terwergreen.com/post/mac-demysql-pei-zhi.html)\n\ndmg安装默认目录\n\n设置环境变量\n\n/usr/local/mysql\n\n找打my.cnf\n\n```\nmysql --verbose --help | grep my.cnf\n```\n\n创建配置 `my.cnf`\n\n```\nvim ~/.my.cnf\n```\n\n设置 `/etc/my.cnf` 也是可以的\n\n比如设置最大连接数\n\n```\nvim /etc/my.cnf\n# 在mysqld节点加上下面的内容\nmax_connections=512\n```\n\n查看\n\n```\nshow variables like \'%max_connections%\';\n```\n\n参考\n\n[https://www.cnblogs.com/phpper/p/9570792.html](https://www.cnblogs.com/phpper/p/9570792.html)', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7961, 'mysql-wang-ji-mi-ma-jie-jue-fang-an', 'MySQL忘记密码解决方案', '2022-04-02 19:41:29', '2022-04-03 11:44:43', '\n\n# 可以空密码登录的情况\n\n```\nmysql -u root -p\n```\n\n修改随机密码为root\n\n```bash\nmysql>\nALTER USER \'root\'@\'localhost\' IDENTIFIED BY \'123456\';\nflush privileges;\n```\n\n# 无法登陆的情况\n\n1、先修改配置文件 `/etc/my.cnf` 令MySQL跳过登录时的权限检验,在 `[mysqld]` 下加入一行:\n\n```bash\nskip-grant-tables\n```\n\n2、重启MySQL\n\n```bash\nservice mysqld restart\n```\n\n3、免密码登录MySQL。\n\n```bash\nmysql\n```\n\n4、修改root密码\n\n```bash\nmysql> use mysql;\nmysql> UPDATE user SET authentication_string = password(\'新密码\') WHERE host = \'localhost\' AND user = \'root\';\nmysql> select host,user, authentication_string, password_expired from user; \nmysql> update user set password_expired=\'N\' where password_expired=\'Y\' //密码不过期\nmysql> update user set host=\'%\' where user=\'root\' and host=\'localhost\'; //远程可访问\nmysql> flush privileges; //刷新权限\nmysql> exit;//退出\n```\n\n5、修改配置文件 `/etc/my.cnf` 删除此前新增那一行 `skip-grant-tables` ,并重启MySQL(这一步非常重要,不执行可能导致严重的安全问题)\n\n```bash\nservice mysqld restart //重启 Mysql\n```\n\n参考:\n\nhttps://help.aliyun.com/document_detail/42520.html\n\n# 错误排查\n\n输入下面的命令然后查看日志\n\n```bash\nmysqld --console\n```\n\n添加链接授权\n\n```bash\nGRANT ALL PRIVILEGES ON *.* TO \'root\'@\'%\' IDENTIFIED BY \'123456\' WITH GRANT OPTION;\n```\n', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7962, 'mac-shi-yongiterm2dai-ti-mo-ren-zhong-duan', 'Mac使用iTerm2代替默认终端', '2022-04-05 19:27:39', '2022-04-06 11:33:04', '\n\n# 下载地址\n\nhttps://iterm2.com/downloads/stable/iTerm2-3_4_15.zip\n\n# 安装\n\n解压后,直接拖进应用程序即可\n\n# 配置管理多个远程链接\n\n## 安装sshpass\n\n下载:http://sourceforge.net/projects/sshpass/files/\n\n解压后,进入sshpass目录,执行安装\n\n```\n./configure\nmake\nmake install\n```\n\n理论上不会出什么问题,安装好后,执行命令检查是否已经OK\n\n```\nsshpass -h\n```\n\n## 创建profile\n\n添加一个新的profile,其它没什么好配置的,主要是在General的command中选择使用command,命令就是sshpass的执行命令,如:\n\n```\n/usr/local/bin/sshpass -p \'123456\' ssh root@127.0.0.1\n```\n', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7963, 'appending-element-is-not-working-in-ie11', 'IE11的append失效问题解决方案', '2022-04-06 18:50:33', '2022-04-07 11:20:31', '\n\n# 问题\n\n一个很简单的动态创建 `select` ,然后添加 `option` 节点的代码,一直运行没问题,结果 `ie11` 却报错了。\n\n```html\n\n```\n\n![](https://cdn.jsdelivr.net/gh/terwer/upload/img/16492982110281.jpg)\n\n# 解决\n\n查了下资料,原来 `ie` 不支持 `element.append` 方法,但是 `element.appendChild` 方法确实所有浏览器通用的。\n\n修改后\n\n```html\n\n```\n\n切记~\n\nIE11(at least my version or settings )did not support `element.append` . It did, however, work as expected with `element.appendChild` .\n\nThe browser compatibility section of MDN confirms that IE ( in contrast to every other browser )has never had ParentNode.append support but has always had Node.appendChild support, which appears to be universal.\n\n# 参考\n\n[Appending element is not working in IE11](https://stackoverflow.com/questions/24705352/appending-element-is-not-working-in-ie11)', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7964, 'mysql-file-descriptor-xxxx-exceeded-fdsetsizexxxx', 'MySQL文件描述符达到限制异常解决:FileDescr...', '2022-04-07 17:37:31', '2022-04-08 10:03:46', '\n\n# 问题\n\n今天早上,MySQL突然无法提供服务了,心想,昨天晚上没有关机啊,怎么回事?\n\n于是去查询日志看看,\n\n```\nsudo tail /usr/local/mysql/data/lryouweitang.local.err\n```\n\n看到了这么一句\n\n```\n2022-04-08T01:33:56.084810Z 0 [Warning] File Descriptor 1049 exceeded FD_SETSIZE=1024\n```\n\n从日志可以发现,是mysql打算持有的文件描述符数量超过了系统的限制。\n\n# 解决\n\n修改下面的参数\n\ntable_open_cache\n\n```\nsudo vim /etc/my.cnf\n```\n\n在 `[mysqld]` 节点改成下面的数组,因为我的系统现在是1024,所以只要比1024小就可以,我这里设置为512。\n\n```\n[mysqld]\ntable_open_cache=512\n```\n\n重启,解决。\n\n```\nsudo /usr/local/MySQL/support-files/mysql.server stop\nsudo /usr/local/MySQL/support-files/mysql.server start\n```', 1, 0, NULL, NULL, 'publish', 'post', 1, 0); +INSERT INTO `posts` VALUES (7965, 'fen-bu-shi-jia-gou-li-lun', '分布式架构理论', '2022-02-28 05:11:39', '2022-04-11 23:59:09', '\n\n## 分布式架构介绍\n\n### 什么是分布式系统\n\n分布式系统是一个硬件或者软件分布在不同的网络计算机上,彼此之间仅仅通过消息传递通信和协调的系统。\n\n通俗的理解,分布式系统是,一个业务分拆成多个子业务,分布在不同的服务器节点,共同构成的服务器系统成为分布式系统。\n\n同一个分布式系统中的服务器节点在空间部署上是可以随意分布的,服务器可能放在不同分机柜中,也可能放在不同不同的机房中,深圳分布在不同的城市。\n\n![image-20220314224421105](https://cdn.jsdelivr.net/gh/terwer/upload/img/image-20220314224421105.png)\n\n### 分布式与集群的区别\n\n集群:多个服务器做同一件事情\n\n![image-20220314224722066](https://cdn.jsdelivr.net/gh/terwer/upload/img/image-20220314224722066.png)\n\n分布式:多个服务器做不同的事情\n\n![image-20220314225045381](https://cdn.jsdelivr.net/gh/terwer/upload/img/image-20220314225045381.png)\n\n### 分布式系统的特性\n\n1、分布性\n\n空间中可以随机分布。这些计算机可以分布在不同机房,不同城市,甚至是不同国家。\n\n2、对等性\n\n分布式系统中的计算机没有主/从之分,组成分布式的所有节点都是对等的。\n\n3、并发性\n\n同一个分布式系统中的多个节点,可能会并发的操作一些共享的资源,例如数据库或者分布式存储。\n\n4、缺乏全局时钟\n\n由于各个计算机依赖交换信息进行通信,很难定义两件事件的先后顺序,缺乏全局时钟控制序列。\n\n5、故障总会发生\n\n组成分布式系统分计算机,都有可能在某一时间崩掉。分的计算机越多,崩的几率越大。如果考虑设计程序时的故障,则故障的概率会大大的增加。\n\n6、处理单点故障\n\n单点SPoF(Single Point of Failure):某个角色或者功能只有某一台计算机在支撑,在这台计算机出现的故障叫做单点故障。\n\n### 分布式系统面临的问题\n\n1. 通信异常\n\n 网络本身不可靠,因此每次通信都会面临网络不可用的风险(光纤、路由器、DNS等硬件系统的不可用),都会导致分布上系统无法顺利进行一次网络通信。即使分布式各个节点直接的网络能够进行通信,延迟也会大于单机操作,存在巨大的时延,这样会影响消息的收发,消息丢失和消息延迟变的很普遍。\n\n![image-20220314231834864](https://cdn.jsdelivr.net/gh/terwer/upload/img/image-20220314231834864.png)\n\n2. 网络分区\n\n 网络中出现了网络不连接,但是各个系统之间的子网链接正常,从而导致网络环境被切割成若干个孤立的区域,分布式系统会出现局部小集群。极端情况下,小集群会完成原本需要整个分布式系统才能完成的任务。包括事务的处理,这对分布式的一致性带来了很大的挑战。\n\n![image-20220314231952023](https://cdn.jsdelivr.net/gh/terwer/upload/img/image-20220314231952023.png)\n\n3. 节点故障\n 指的是分布式系统中节点出现宕机,每个节点又有可能出现故障或者僵死,并且经常发生。\n\n![image-20220314232419799](https://cdn.jsdelivr.net/gh/terwer/upload/img/image-20220314232419799.png)\n\n4. 三态\n\n 分布式系统中每一次请求都存在三态,即:成功、失败和超时。\n\n![image-20220314232625668](https://cdn.jsdelivr.net/gh/terwer/upload/img/image-20220314232625668.png)\n\n5. 重发\n\n 分布式系统在调用是可能会发生 `失败` 和 `超时` ,这时需要重新发起调用。\n\n![image-20220314232852790](https://cdn.jsdelivr.net/gh/terwer/upload/img/image-20220314232852790.png)\n\n6. 幂等\n\n 一次或者多次请求同一个资源本身应该有相同的结果(网络超时等问题除外)。即任意多次执行对资源本身产生的影响均与第一次执行的影响相同。\n\n![image-20220314233421353](https://cdn.jsdelivr.net/gh/terwer/upload/img/image-20220314233421353.png) ![image-20220314233522102](https://cdn.jsdelivr.net/gh/terwer/upload/img/image-20220314233522102.png) ![image-20220314233559509](https://cdn.jsdelivr.net/gh/terwer/upload/img/image-20220314233559509.png)\n\n## 分布式理论\n\n### 数据一致性\n\n#### 什么是分布式数据一致性\n\n分布性数一致性,指的是数据在多份副本中存储时,各副本中的数据是一致的。\n\n![image-20220317203744981](https://cdn.jsdelivr.net/gh/terwer/upload/img/image-20220317203744981.png)\n\n#### 副本一致性\n\n分布式系统中,数据往往会有读个副本。多个副本就需要保证数据一致性。这就带来了同步的问题,因为网络阻塞等因素,我们几乎无法保证可以同时更新所有机器中的所有数据,就会有数据不一致。\n\n![image-20220317204315708](https://cdn.jsdelivr.net/gh/terwer/upload/img/image-20220317204315708.png)\n\n总之,无法找到满足分布式系统数据一致性的解决方案。因此,如何保证数据一致性,同时又不影响性能,是每一个分布式系统需要考虑和权衡的。所以,就产生了一致性级别。\n\n#### 一致性分类\n\n1. 强一致性\n\n 符合用户直觉的。它要求用户写进去是什么,读出来就是什么。用户体验好,但是实现起来对性能影响较大。强一致性很难实现。\n\n2. 弱一致性\n\n 约束了系统在写入成功后,不承诺立即读到写入的值,也不承诺数据多久达成一致,但是会尽可能保证某个时间级别(比如秒级别)后,数据能达到一致。\n\n3. 最终一致性\n\n **最终一致性是弱一致性的一种**,无法保证数据更新后,后续所有访问都能获取到最新值,需要一个时间,在这个时间之后可以保证这一点(**在一个时间节点之后,数据会最终达到一致**)。在这个时间之内,数据可能会不一致,这个系统无法保证强一致性的时间片段被称为不一致窗口。不一致时间窗口的时间长短取决于很多因素,比如备份数据的个数、网络传输延迟、系统负载等。\n \n\n![image-20220317210009123](https://cdn.jsdelivr.net/gh/terwer/upload/img/image-20220317210009123.png)\n最终一致性在实际应用中有很多变种\n\n- 因果一致性\n\n 如果进程A通知进程B更新了一个数据项,那么进程B的后续访问将返回更新后的值。与进程A无因果关系的进程C的访问将遵守一般的最终一致性规则。\n\n![image-20220317215154546](https://cdn.jsdelivr.net/gh/terwer/upload/img/image-20220317215154546.png)\n\n- 读已之所写一致性\n\n 当进程A更新一个数据项之后,它总是访问到更新过的值,不会看到旧值。这是因果一致性的特例。\n\n![image-20220317222852440](https://cdn.jsdelivr.net/gh/terwer/upload/img/image-20220317222852440.png)\n\n- 会话一致性\n\n 把访问存储系统的进程放到会话的上下文。只要会话还在,就能保证”读己之所写一致性“。如果由于某些失败情形会话终止,就要建立新的会话,而且系统的保证不会延续到新的会话。\n\n![image-20220317223501094](https://cdn.jsdelivr.net/gh/terwer/upload/img/image-20220317223501094.png)\n\n- 单调读一致性\n\n 如果一个进程已经读取到一个特定值,那么该进程不会读取到该值以前的任何值。\n \n\n![image-20220317224143281](https://cdn.jsdelivr.net/gh/terwer/upload/img/image-20220317224143281.png)\n\n- 单调写一致性\n \n 系统保证对同一个进程的写操作串行化。\n \n\n![image-20220317224245157](https://cdn.jsdelivr.net/gh/terwer/upload/img/image-20220317224245157.png)\n#### 一致性模型图\n\n![image-20220317224446843](https://cdn.jsdelivr.net/gh/terwer/upload/img/image-20220317224446843.png)\n### CAP定理\n\n#### CAP定理介绍\n\nCAP定理(CAP Theorem),又称布鲁尔定理(Brewer\'s throrem)。它指出,对一个分布式系统来说,不可能同时满足以下三点:\n\n| 选项 | 具体意义 |\n| --------------------------------- | ------------------------------------------------------------ |\n| 一致性(Consistency) | 所有节点访问时都是同一份最新的数据副本 |\n| 可用性(Availability) | 每次请求都能获取到非错的响应,但是不保证获取数据为最新数据 |\n| 分区容错性(Partition tolarence) | 分布式系统在遇到任何网络分区故障的时候,仍然能够对外提供满足一致性和可用性的服务,除非整个网络环境发生了故障 |\n\n- 一致性(Consistency)- C\n\n **指的是强一致性**\n\n 在写操作完成后开始的任何读操作都必须返回该值,或者后续写操作的结果。\n\n 就是说,在分布式系统中,一旦客户端将值写入任何一台服务器并获得相应,那么之后client从其他服务器读取的都是刚写入的数据。\n\n![image-20220317230127717](https://cdn.jsdelivr.net/gh/terwer/upload/img/image-20220317230127717.png)\n\n - 客户端向G1写入数据,并等待响应\n - 此时,G1服务器的数据是v1,G2服务器的数据是v0,不一致\n - 在返回数据到客户端之前,G2服务器会自动同步G1服务器的数据,使G2服务器的数据也是v1\n - 一致性保证了,不管向哪台服务器(比如G1)写入数据,其他服务器都能实时同步数据\n - G2已经同步了G1的数据,会告诉G1,我已经同步了\n - G1接收了同步的报告,将”写入成功“的信息返回给client\n - client在发起请求,读取G2的数据\n - 此时读取到的响应值是v1\n \n- 可用性(Availability)- A\n\n 系统中非故障性节点的每个请求都必须有响应。\n\n 可用系统中,如果客户端向服务端发送请求,并且服务器未崩溃,则服务器必须最终响应客户端,不允许服务端忽略客户端的请求。\n\n- 分区容错性(Partition tolarence) - P\n\n 允许网络丢失从一个节点到另一个节点的任意条消息,即不同步。\n \n 就是说,G1和G2发送给客户端的任意消息都可以放弃。\n \n G1和G2可能会因为各种意外状况,导致无法成功同步,分布式系统能容忍这种情况。\n \n\n![image-20220317232109808](https://cdn.jsdelivr.net/gh/terwer/upload/img/image-20220317232109808.png)\n#### CAP三者不能同时满足结论\n\n假设存在三者都能满足的系统\n\n1、那么做的第一件事就是分区我们的系统,由于满足分区容错性,也就是说,可能因为网络通信不佳,导致G1和G2不同步\n\n![image-20220317233342357](https://cdn.jsdelivr.net/gh/terwer/upload/img/image-20220317233342357.png)\n\n2、接下来,我们的客户端将v1写入G1,但是G1和G2之间是不同步的,所以如下,G1是v1的数据,G2是v0的数据\n\n![image-20220318095813714](https://cdn.jsdelivr.net/gh/terwer/upload/img/image-20220318095813714.png)\n\n3、由于要满足可用性,即一定要返回数据,所以G1必须在数据没有同步给G2的前提下返回数据给client,如下\n\n![image-20220318101516244](https://cdn.jsdelivr.net/gh/terwer/upload/img/image-20220318101516244.png)\n\n接下来,client请求的是G2服务器,由于G2服务器的数据是v0,那么client得到的数据也是v0\n\n![image-20220318101730019](https://cdn.jsdelivr.net/gh/terwer/upload/img/image-20220318101730019.png)\n\n结论:G1返回的是v1的数据,G2返回的是v0的数据,不满足C。因此得证,CAP不可能同时出现。\n\n![image-20220318102130059](https://cdn.jsdelivr.net/gh/terwer/upload/img/image-20220318102130059.png)\n\n#### CAP三者如何平衡\n\n ##### 三选二利弊如何\n\n- CA(Consistency + Availability),关注一致性和可用性,他需要非常严格的全体一致性协议。\n\n CA系统不能容忍网络错误或者节点错误,一旦出现这样的问题,系统就会拒绝写请求。\n\n 因为它并不知道哪个节点挂掉了或者只是网络故障问题。\n\n 唯一安全的做法是把自己变成只读的。\n\n![image-20220318102935087](https://cdn.jsdelivr.net/gh/terwer/upload/img/image-20220318102935087.png)\n\n- CP(Consistency + Pattition tolerance),关注一致性和分区容错性。他关注的是系统中大部分人的一致性协议。这种系统只需要保证大多数节点数据一致,少数节点在没有同步到最新数据时,变成不可用状态。\n\n 这样能够提供一部分可用性。\n\n![image-20220318103603711](https://cdn.jsdelivr.net/gh/terwer/upload/img/image-20220318103603711.png)\n\n- AP(Availability +Pattition tolerance),关系可用性和分区容错性。\n\n 这样的系统不能保证一致性,需要给出数据冲突,给出数据冲突就需要维护数据版本。\n\n![image-20220318105221075](https://cdn.jsdelivr.net/gh/terwer/upload/img/image-20220318105221075.png)\n\n##### 三选二如何选择\n\n​ 放弃了一致性,满足容错,那么节点之间可能失去联系,为了高可用,每个节点只能使用本地数据提供服务,而这样容易导致全局不一致性。\n\n​ 对于互联网应用来说,机器数量庞大,节点分散,网络故障很正常,此时就是保障AP,放弃C的场景。实际理解就是,网站偶尔没有一致性是可以接受的,但是不能访问问题就很大。\n\n![image-20220318105337120](https://cdn.jsdelivr.net/gh/terwer/upload/img/image-20220318105337120.png)\n\n​ 对于银行来说,C必须存在,那么只能用CA和CP两种情况。当保障一致性和可用性时(CA),那么一旦出现通信故障,系统将完全不可用。如果保障了一致性和分区容错性(CP),那么就具备了部分可用性。需要根据实际情况抉择,如果只是查看不做更新,那么不如直接拒绝服务。\n\n![image-20220318110449358](https://cdn.jsdelivr.net/gh/terwer/upload/img/image-20220318110449358.png)\n\n### BASE定理\n\nCAP不可能同时满足,但是分区容错性对于分布式系统来说,是必须的。如果能够同时满足CAP就好了,于是出现了BASE理论。\n\nBASE:全称Basically Availability(基本可用),Soft State(软状态),和Eventually Consistency(最终一致性),三个短语的缩写。\n\nBASE定理是对CAP中一致性和可用性权衡的结果,来源于对大型互联网分布式实践的总结,是基于CAP定理逐步演化而来。\n\n核心思想是:即使无法做到强一致性(Strong Consistency),但是每个应用可以根据自身的特点,采取适当的方式让系统达到最终一致性(Eventually Consistency)。\n\n1. Basically Availability(基本可用)\n\n 什么是基本可用?就是相对于正常系统而言,系统虽然出现了不可预知的故障,但是还是能用。\n\n - 响应时间上的损失:正常情况下的搜索引擎在0.5秒给出搜索结果,基本可用的搜索引擎在1秒给出搜索结果\n\n - 功能上的损失:在电商网站上,正常情况下,用户可以完成每一笔订单,但是,在大促销期间,为了保证购物系统的稳定,部分消费者会被引导到一个降级页面\n\n![image-20220318175020403](https://cdn.jsdelivr.net/gh/terwer/upload/img/image-20220318175020403.png)\n\n2. Soft State(软状态)\n\n 什么是软状态?对于原子性而言,要求多个节点的副本数据是一致的,这是一种硬状态。\n\n 软状态指的是:允许系统中的数据存在中间状态,并认为该状态不会影响系统的整体可用性。\n\n 就是允许系统在多个不同节点的数据副本存在数据延迟。\n\n3. (Eventually Consistency)最终一致性\n\n 软状态不可能一致持续,必须有个期限。\n\n 在期限过后,应当保证所有副本的数据一致性。从而达到数据的最终一致性。\n\n 时间期限取决于网络延迟,系统负载,数据复制方案设计等因素。\n\n## 分布式一致性协议\n\n### 两阶段提交协议(2PC)\n\n#### 两阶段提交协议\n\n两阶段提交协议,简称2PC(2 prepare commit),是比较常见的解决分布式事务的方式。要么所有参与进程都提交事务,要么都取消事务,即实现ACID中的原子性(A)的常用手段。\n\n分布式事务:事务提供一种操作本地数据库的不可分割的一系列操作。要么什么都不做,要么做全套(All or Nothing)。\n\n分布式事务是为了操作不同数据库的不可分割的一系列操作。要么什么都不做,要么做全套(All or Nothing)。\n\n![image-20220320193312964](https://cdn.jsdelivr.net/gh/terwer/upload/img/image-20220320193312964.png)\n\n#### 2PC执行流程\n\n- 成功提交事务的流程\n\n![image-20220320193849595](https://cdn.jsdelivr.net/gh/terwer/upload/img/image-20220320193849595.png)\n\n - 阶段一\n\n - 事务询问\n\n 协调者向所有事务参与者发送事务内容,询问是否可以执行事务提交操作,并且开始等待各个参与者的响应\n\n - 执行事务(写本地的undo/redo日志)\n\n - 各个参与者向事务协调者反馈事务询问的响应\n\n - 阶段二\n\n - 发送提交请求\n \n 协调者向所有参与者发送commit请求\n \n - 事务提交\n \n 参与者收到commit请求后,正式执行事务提交操作,完成提交操作后释放整个事务执行期间占用的事务资源\n \n - 反馈事务提交结果\n \n 参与者在完成事务提交后,向协调者发送ack消息\n \n - 完成事务\n \n 协调者接收到参与者发送的ack消息,完成事务\n\n- 中断事务流程\n\n 假设任意一个参与者向协调者发送了No响应,或者在等待超时之后,协调者还是无法接收到参与者的响应,那么就会中断事务。\n\n![image-20220320194926824](https://cdn.jsdelivr.net/gh/terwer/upload/img/image-20220320194926824.png)\n\n - 阶段一\n\n - 事务询问\n\n 协调者向所有事务参与者发送事务内容,询问是否可以执行事务提交操作,并且开始等待各个参与者的响应\n\n - 执行事务(写本地的undo/redo日志)\n\n - 各个参与者向事务协调者反馈事务询问的响应\n\n - 阶段二\n\n - 发送回滚请求\n\n 协调者向所有参与者发送rollback请求\n\n - 事务回滚\n\n 参与者解释道rollback请求之后,利用在阶段一中记录的undo信息,来执行事务回滚操作。并在完成事务回滚之后释放在整个事务执行期间占用的事务资源。\n\n - 反馈事务回滚结果\n\n 参与者完成事务回滚之后,向协调者发送ack消息\n\n - 中断事务\n\n 协调者接收到所有参与者发送的ack消息之后,完成事务中断\n\n#### 2PC优缺点\n\n- 优点\n\n 原理简单\n\n- 缺点\n\n - 同步阻塞\n \n 在二阶段提交的执行的过程中,所有参与该事务操作的逻辑都处于堵塞状态。\n \n 当参与者占用公共资源时,其他参与者一直处于锁定事务资源的状态中,而无法完成事务操作。\n \n - 单点问题\n \n 若协调器出现问题,那么整个第二阶段的事务提交将无法运转,若协调者在阶段二出现问题,其他参与者一直处于锁定事务资源的状态中,无法完成事务操作\n \n - 数据不一致\n \n 在阶段二中,执行事务提交的的时候,当协调者向所有参与者发送commit请求之后,发生了网络异常,或者,协调者尚未发送commit请求之前发生了崩溃,导致最终只有部分参与者收到了commit请求,就会出现数据不一致的情况\n \n - 太过保守\n \n 在进行事务提交询问的过程中,参与者出现故障而导致协调者始终无法获取所有参与者的响应信息的话,此时协调者只能通过自己的超时机制来判断是否需要终止事务。\n \n 这样的策略过于保守,既没有完善的容错机制,任意一个节点的失败都会导致整个事务的失败。\n\n### 三阶段提交协议(3PC)\n\n三阶段提交协议出现的背景:一致性协议中设计出了二阶段提交协议,但是2PC设计存在缺陷,于是有了三阶段提交协议\n\n#### 三阶段提交协议\n\n3PC,全称为“Three phase commit”,是2PC的改进版,将2PC的“事务提交过程”一分为二,并形成了canCommit、preCommit和doCommit三个阶段组成的事务处理协议。\n\n![image-20220320223801310](https://cdn.jsdelivr.net/gh/terwer/upload/img/image-20220320223801310.png)\n\n三阶段提交升级点(基于二阶段):\n\n- 三阶段提交协议引入了超时机制\n\n- 在第一阶段和第二阶段中,引入了一个准备阶段。保证最后提交之前,各个节点之间数据一致性。\n\n 简单地说:除了引入超时机制外,3PC把2PC的准备阶段再次一分为二,这样三阶段提交就有,CanCommit、\n \n preCommit、doCommit三个阶段。\n\n#### 三阶段详解\n\n- 第一阶段(canCommit)\n\n 类似于2PC的准备阶段(preCommit)。\n\n 协调者向参与者发送Commit请求,参与者如果可以提交就发生yes响应,否则返回No响应。\n\n - 事务询问\n\n 协调者向参与者发送canCommit请求。询问是否可以进行事务提交操作,然后开始等待参与者的响应。\n\n - 响应反馈\n\n 参与者接收到canCommit请求之后,正常情况下,如果自身可以执行事务,则返回Yes响应,并进入预备状态。否则反馈No\n\n- 第二阶段(preCommit)\n\n 协调者根据参与者的反应情况,来决定是否可以执行事务的preCommit操作。根据响应情况,有以下两种可能:\n\n - Yes\n\n (1)发送预提交请求\n\n 协调者向参与者发送preCommit请求,并进入prepared阶段。\n\n (2)事务预提交\n\n 参与者接收到preCommit请求之后,会执行事务操作,并将undo信息和redo信息记录到事务日志中。\n\n (3)响应反馈\n\n 如果参与者成功执行了事务操作,则返回ACK响应,并且开始等待最终指令。\n\n - No\n\n 假设任何一个向协调者发送了No响应,或者等待超时之后,协调者都没有接收到参与者的响应,那么就执行事务的中断。\n\n (1)发送中断请求\n \n 协调者向参与者发送abort请求\n \n (2)中断事务\n \n 参与者收到来着协调者的abort请求之后(或者超时仍未收到协调者的请求),执行事务的中断\n\n- 第三阶段(doCommit)\n\n 该阶段进行真正的事务提交,也可以分为执行事务和中断事务两种情况\n\n - 执行成功\n \n (1)发送提交请求\n \n 协调者接收到参与者发送的ACK响应,那么它从预提交状态进入到提交状态。并向所有参与者发送doCommit请求。\n \n (2)事务提交\n \n 参与者接收到doCommit请求之后,执行正式的事务提交。并在完成事务提交之后释放所有的事务资源。\n \n (3)响应反馈\n \n 事务提交完之后,向协调者发送ACK响应。\n \n (4)完成事务\n \n 协调者接收到所有参与者的ACK响应之后,完成事务。\n \n - 中断事务\n \n (1)发送中断请求\n \n 协调者向所有参与者发送abort请求\n \n (2)事务回滚\n \n 参与者接收到abort请求之后,利用在阶段二记录的undo信息来执行事务的回滚操作,并在完成回滚之后释放所有的事务资源。\n \n (3)反馈结果\n \n 参与者完成事务回滚之后,想协调者发送ACK消息\n \n (4)中断事务\n \n 协调者接收到所有参与者的ACk消息之后,进行事务的中断\n \n 一旦进入阶段三,可能会有两种故障\n \n (1)协调者出现问题\n \n (2)协调者和参与者之间的网络故障\n \n\n![image-20220327152939588](https://cdn.jsdelivr.net/gh/terwer/upload/img/image-20220327152939588.png)\n\n 如果出现了任何一种情况,都可能出现参与者无法收到doCommit请求或者abort请求,参与者都会在等待超时之后进行事务提交。\n\n#### 3PC和2PC对比\n\n对于协调者和参与者都设置了超时协议(在2PC中,只有协调者有超时机制,如果在一定时间内没有收到参与者的消息默认失败)。主要避免了参与者长时间无法与协调者节点通讯的情况下(或者协调者挂掉),无法释放资源的问题。因为参与者自身有超时机制,会在超时后,自动进行本地commit而释放资源。这种机制从侧面降低了整个事务的阻塞时间和范围。\n\n通过canCommit、preCommit、doCommit三个阶段设计,相对于2PC而言,多设置了一个缓冲阶段,保证了最后提交阶段之前各个参与节点的状态一致。\n\npreCommit是一个缓冲,保证了最后提交节点之前,各个节点的状态是一致的。\n\n**3PC没有完全解决数据一致性的问题。**\n\n### NWR协议\n\n#### 什么是NWR协议\n\nNWR是一种在分布式存储系统中用于控制一致性级别的一种策略。在亚马逊的存储系统中,应用了NWR协议来控制一致性。\n\n- N:在分布式系统中,有多少分备份数据\n- W:代表一次成功的更新操作要求至少有W份写入成功\n- R:代表一次成功的读取操作至少有R份读取成功\n\n#### 原理\n\nNWR值的不同组合会产生不同的一致性效果,当W+R>N 时,整个系统对客户端来讲能够保证强一致性。\n\n**以常见的N=3、W=2、R=2来举例**\n\n- N=3,表示,任何一个对象都必须有三个副本\n- W=2,表示,对数据的修改,只需要在三个副本中的两个上面完成就返回\n- R=2,表示,从三个对象中读取两个对象,才能返回\n\n在分布式系统中,数据的 单点是不允许存在的。也就是线上存在的备份数量N=1是非常危险的。因为一旦这个备份发生错误,就可能发生数据的永久性错误。假如我们把N设置为2,那么,只要有一个存储节点发生错误,就会有单点的存在。**所有N必须大于2。**N越大,系统的维护成本也越高。工业界通常把N设置为3。\n\n![image-20220327233803133](https://cdn.jsdelivr.net/gh/terwer/upload/img/image-20220327233803133.png)\n\n1、当W是2、R是2的时候,W+R>N ,这种情况对于客户端是强一致性的。\n\n如果,W+R>N,那么读取和写入成功的数据一定存在交集。这样就能保证一定能够读取到最新的数据,数据的强一致性得到了保证。在满足数据一致性的前提下,R或者W的值设置的越大,则系统延迟越大,因为这取决于最慢的那份备份数据的响应时间。\n\n2、当R+W Date: Mon, 20 Jun 2022 01:42:53 +0800 Subject: [PATCH 5/6] =?UTF-8?q?feat=E6=96=B0=E5=A2=9Exmlrpc=E6=94=AF?= =?UTF-8?q?=E6=8C=81metaweblog=EF=BC=8C=E5=8F=AF=E4=BD=BF=E7=94=A8MWeb?= =?UTF-8?q?=E5=8F=91=E5=B8=83=E6=96=87=E7=AB=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jvue-server/pom.xml | 19 ++ .../jvueserver/JVueServerApplication.java | 25 +- .../jvueserver/constant/JVueConstants.java | 12 + .../coresevice/aliyunoss/OssManager.java | 81 ++++++ .../coresevice/xmlrpc/IMetaWeblog.java | 91 ++++++ .../coresevice/xmlrpc/MetaWeblogImpl.java | 268 ++++++++++++++++++ .../jvueserver/util/SpringBeanUtils.java | 42 +++ .../resources/mappers/spl-mapping-post.xml | 9 + .../xmlrpc/webserver/XmlRpcServlet.properties | 2 + 9 files changed, 546 insertions(+), 3 deletions(-) create mode 100644 jvue-server/src/main/java/com/terwergreen/jvueserver/constant/JVueConstants.java create mode 100644 jvue-server/src/main/java/com/terwergreen/jvueserver/coresevice/aliyunoss/OssManager.java create mode 100644 jvue-server/src/main/java/com/terwergreen/jvueserver/coresevice/xmlrpc/IMetaWeblog.java create mode 100644 jvue-server/src/main/java/com/terwergreen/jvueserver/coresevice/xmlrpc/MetaWeblogImpl.java create mode 100644 jvue-server/src/main/java/com/terwergreen/jvueserver/util/SpringBeanUtils.java create mode 100644 jvue-server/src/main/resources/org/apache/xmlrpc/webserver/XmlRpcServlet.properties diff --git a/jvue-server/pom.xml b/jvue-server/pom.xml index 55ee9ea..88c7702 100644 --- a/jvue-server/pom.xml +++ b/jvue-server/pom.xml @@ -126,6 +126,25 @@ 2.9.2 + + + org.apache.xmlrpc + xmlrpc-server + 3.1.3 + + + javax.servlet + servlet-api + + + + + + com.aliyun.oss + aliyun-sdk-oss + 3.13.2 + + org.springframework.boot diff --git a/jvue-server/src/main/java/com/terwergreen/jvueserver/JVueServerApplication.java b/jvue-server/src/main/java/com/terwergreen/jvueserver/JVueServerApplication.java index 64e093f..68b975d 100644 --- a/jvue-server/src/main/java/com/terwergreen/jvueserver/JVueServerApplication.java +++ b/jvue-server/src/main/java/com/terwergreen/jvueserver/JVueServerApplication.java @@ -1,13 +1,32 @@ package com.terwergreen.jvueserver; +import com.terwergreen.jvueserver.constant.JVueConstants; +import com.terwergreen.jvueserver.util.SpringBeanUtils; +import org.apache.xmlrpc.webserver.XmlRpcServlet; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.ServletRegistrationBean; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.Bean; @SpringBootApplication public class JVueServerApplication { - public static void main(String[] args) { - SpringApplication.run(JVueServerApplication.class, args); - } + public static void main(String[] args) { + //设置应用类型 + SpringApplication springApplication = new SpringApplication(JVueServerApplication.class); + // 启动Spring Boot + ConfigurableApplicationContext applicationContext = springApplication.run(args); + // 提供给上下文工具 + SpringBeanUtils.setContext(applicationContext); + } + @SuppressWarnings({"unchecked", "rawtypes"}) + @Bean + public ServletRegistrationBean registerServlet() { + return new ServletRegistrationBean( + new XmlRpcServlet(), + JVueConstants.CONSTANT_XMLRPC_NAME // xml-rpc访问接口 + ); + } } diff --git a/jvue-server/src/main/java/com/terwergreen/jvueserver/constant/JVueConstants.java b/jvue-server/src/main/java/com/terwergreen/jvueserver/constant/JVueConstants.java new file mode 100644 index 0000000..879463d --- /dev/null +++ b/jvue-server/src/main/java/com/terwergreen/jvueserver/constant/JVueConstants.java @@ -0,0 +1,12 @@ +package com.terwergreen.jvueserver.constant; + +/** + * 常用常量 + * + * @name: JVueConstants + * @author: terwer + * @date: 2022-06-20 00:53 + **/ +public class JVueConstants { + public static final String CONSTANT_XMLRPC_NAME = "/xmlrpc"; +} diff --git a/jvue-server/src/main/java/com/terwergreen/jvueserver/coresevice/aliyunoss/OssManager.java b/jvue-server/src/main/java/com/terwergreen/jvueserver/coresevice/aliyunoss/OssManager.java new file mode 100644 index 0000000..7f1aa29 --- /dev/null +++ b/jvue-server/src/main/java/com/terwergreen/jvueserver/coresevice/aliyunoss/OssManager.java @@ -0,0 +1,81 @@ +package com.terwergreen.jvueserver.coresevice.aliyunoss; + +import com.aliyun.oss.ClientException; +import com.aliyun.oss.OSS; +import com.aliyun.oss.OSSClientBuilder; +import com.aliyun.oss.OSSException; +import com.aliyun.oss.model.OSSObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +/** + * endpoint + * accessKeyId 阿里云自己申请的 + * accessKeySecret 阿里云自己申请的 + * token 后台生成 + */ +public class OssManager { + private static final Logger logger = LoggerFactory.getLogger(OssManager.class); + + private static final String ENDPOINT = "http://oss-cn-qingdao.aliyuncs.com"; + private static final String ACCESS_KEY = "I2qcXHrK0sU1cM26"; + private static final String ACCESS_SECRET = "APQh3jSW1reSJcgAPY7pqVKFOPVJM4"; + private static final String BUCKET_NAME = "terwer"; + + private static OSS client = null; + + public static OssManager getInstance() { + return OssInstance.instance; + } + + private static class OssInstance { + private static final OssManager instance = new OssManager(); + } + + private OssManager() { + } + + public void upload(String name, byte[] bytes) { + try { + client = new OSSClientBuilder().build(ENDPOINT, ACCESS_KEY, ACCESS_SECRET); + + /* + * Create an empty folder without request body, note that the key must be + * suffixed with a slash + */ + client.putObject(BUCKET_NAME, name, new ByteArrayInputStream(bytes)); + + /* + * Verify whether the size of the empty folder is zero + */ + OSSObject object = client.getObject(BUCKET_NAME, name); + logger.info("Size of the file '" + object.getKey() + "' is " + + object.getObjectMetadata().getContentLength()); + object.getObjectContent().close(); + + } catch (OSSException oe) { + logger.error("Caught an OSSException, which means your request made it to OSS, " + + "but was rejected with an error response for some reason."); + logger.error("Error Message: " + oe.getErrorMessage()); + logger.error("Error Code: " + oe.getErrorCode()); + logger.error("Request ID: " + oe.getRequestId()); + logger.error("Host ID: " + oe.getHostId()); + } catch (ClientException ce) { + logger.error("Caught an ClientException, which means the client encountered " + + "a serious internal problem while trying to communicate with OSS, " + + "such as not being able to access the network."); + logger.error("Error Message: " + ce.getMessage()); + } catch (IOException e) { + e.printStackTrace(); + } finally { + /* + * Do not forget to shut down the client finally to release all allocated resources. + */ + client.shutdown(); + } + } +} diff --git a/jvue-server/src/main/java/com/terwergreen/jvueserver/coresevice/xmlrpc/IMetaWeblog.java b/jvue-server/src/main/java/com/terwergreen/jvueserver/coresevice/xmlrpc/IMetaWeblog.java new file mode 100644 index 0000000..d822a69 --- /dev/null +++ b/jvue-server/src/main/java/com/terwergreen/jvueserver/coresevice/xmlrpc/IMetaWeblog.java @@ -0,0 +1,91 @@ +package com.terwergreen.jvueserver.coresevice.xmlrpc; + +import org.apache.xmlrpc.XmlRpcException; + +import java.util.List; +import java.util.Map; + +/** + * metaWeblogApi接口定义 + * + * @name: IMetaWeblog + * @author: terwer + * @date: 2022-03-07 13:30 + **/ +public interface IMetaWeblog { + /** + * 获取博客信息:blogger.getUsersBlogs + * @param appKey + * @param username + * @param password + * @return + * @throws XmlRpcException + */ + List> getUsersBlogs(String appKey, String username, String password) throws XmlRpcException; + + /** + * 发布博客文章:metaWeblog.newPost + * @param blogid + * @param username + * @param password + * @param post + * @param publish + * @return + * @throws XmlRpcException + */ + String newPost(String blogid, String username, String password, Map post, boolean publish) throws XmlRpcException; + + /** + * 编辑博客文章:metaWeblog.editPost + * @param postid + * @param username + * @param password + * @param post + * @param publish + * @return + * @throws XmlRpcException + */ + boolean editPost(String postid, String username, String password, Map post, boolean publish) throws XmlRpcException; + + /** + * 获取博客文章:metaWeblog.getPost + * @param postid + * @param username + * @param password + * @return + * @throws XmlRpcException + */ + Map getPost(String postid, String username, String password) throws XmlRpcException; + + /** + * 获取博客分类:metaWeblog.getCategories + * @param blogid + * @param username + * @param password + * @return + * @throws XmlRpcException + */ + List> getCategories(String blogid, String username, String password) throws XmlRpcException; + + /** + * 获取最近的文章列表:metaWeblog.getRecentPosts + * @param blogid + * @param username + * @param password + * @param numberOfPosts + * @return + * @throws XmlRpcException + */ + List> getRecentPosts(String blogid, String username, String password, int numberOfPosts) throws XmlRpcException; + + /** + * 上传媒体对象:metaWeblog.newMediaObject + * @param blogid + * @param username + * @param password + * @param post + * @return + * @throws XmlRpcException + */ + Map newMediaObject(String blogid, String username, String password, Map post) throws XmlRpcException; +} diff --git a/jvue-server/src/main/java/com/terwergreen/jvueserver/coresevice/xmlrpc/MetaWeblogImpl.java b/jvue-server/src/main/java/com/terwergreen/jvueserver/coresevice/xmlrpc/MetaWeblogImpl.java new file mode 100644 index 0000000..4846a2f --- /dev/null +++ b/jvue-server/src/main/java/com/terwergreen/jvueserver/coresevice/xmlrpc/MetaWeblogImpl.java @@ -0,0 +1,268 @@ +package com.terwergreen.jvueserver.coresevice.xmlrpc; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.terwergreen.jvueserver.core.CommonService; +import com.terwergreen.jvueserver.coresevice.aliyunoss.OssManager; +import com.terwergreen.jvueserver.model.Post; +import com.terwergreen.jvueserver.model.SiteConfig; +import com.terwergreen.jvueserver.service.PostService; +import com.terwergreen.jvueserver.service.UsersService; +import com.terwergreen.jvueserver.util.ReflectUtil; +import com.terwergreen.jvueserver.util.SpringBeanUtils; +import org.apache.xmlrpc.XmlRpcException; +import org.apache.xmlrpc.common.XmlRpcNotAuthorizedException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.nio.charset.StandardCharsets; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +/** + * metaWeblogApi的具体实现 + * + * @name: MetaWeblogImpl + * @author: terwer + * @date: 2022-03-07 14:09 + **/ +public class MetaWeblogImpl implements IMetaWeblog { + private static final Logger logger = LoggerFactory.getLogger(MetaWeblogImpl.class); + + private CommonService commonService; + private Object userService; + private PostService postService; + + public CommonService getCommonService() { + if (commonService == null) { + commonService = SpringBeanUtils.getBean(CommonService.class); + } + return commonService; + } + + public PostService getPostService() { + if (postService == null) { + postService = SpringBeanUtils.getBean(PostService.class); + } + return postService; + } + + public Object getUserService() { + if (userService == null) { + userService = (UsersService) SpringBeanUtils.getBean("userService"); + // userService = SpringBeanUtils.getBean("com.terwergreen.plugins.auth.service.impl.UserService"); + } + return userService; + } + + public MetaWeblogImpl() { + logger.info("容器中注册MetaWeblogImpl"); + } + + private Map isValid(String username, String password) throws XmlRpcNotAuthorizedException { + logger.info("username: {}, password: {}", username, password); + Map rtnResult = new HashMap<>(); +// Object userService = getUserService(); +// Map rtnResult = (Map) ReflectUtil.invoke(userService, "isValid", new Class[]{String.class, String.class}, +// new Object[]{username, password}); +// boolean isValid = (boolean) rtnResult.get("matches"); +// logger.info("isValid = {}", isValid); +// if (!isValid) { +// throw new XmlRpcNotAuthorizedException("账号或密码有误"); +// } + return rtnResult; + } + + public List> getUsersBlogs(String appKey, String username, String password) throws XmlRpcException { + logger.info("[blogger.getUsersBlogs] -> appKey: {}, username: {}, password: {}", appKey, username, password); + isValid(username, password); + + SiteConfig siteConfig = getCommonService().getSiteConfig(); + + List> usersBlogs = new ArrayList<>(); + Map blogInfo = new HashMap<>(); + blogInfo.put("blogid", "JVue"); + blogInfo.put("url", siteConfig.getWeburl()); + blogInfo.put("blogName", siteConfig.getWebname()); + usersBlogs.add(blogInfo); + + return usersBlogs; + } + + @Override + public String newPost(String blogid, String username, String password, Map post, boolean publish) throws XmlRpcException { + // logger.info("metaWeblog.newPost -> blogid: {}, post: {}, publish: {}", blogid, JSON.toJSONString(post), publish); + logger.info("metaWeblog.newPost -> blogid: {}, publish: {}", blogid, publish); + Map rtnResult = isValid(username, password); + + JSONObject postJson = JSONObject.parseObject(JSON.toJSONString(post)); + // logger.debug("postJson = {}", postJson); + + Integer postId = 0; + Map pramMap = new HashMap(); + try { + Post postObj = new Post(); + // ========== + // 数据转换开始 + // ArticleCategory ac = getCategory(postJson.getJSONArray("categories")); + // article.setCategory(ac); + postObj.setTitle(postJson.getString("title")); + postObj.setContent(postJson.getString("description")); + postObj.setTags(postJson.getString("mt_keywords")); + postObj.setName(postJson.getString("wp_slug")); + postObj.setStatus(postJson.getString("post_status")); + postObj.setCreated(postJson.getDate("dateCreated")); + // post page essay note + postObj.setType("post"); + postObj.setAuthorId(1); + // 数据转换结束 + // ========== + + postId = getPostService().savePost(postObj).getId(); + logger.info("postId = {}", postId); + } catch (Exception e) { + e.printStackTrace(); + throw new XmlRpcException(500, e.getMessage()); + } + + return postId + ""; + } + + @Override + public boolean editPost(String postid, String username, String password, Map post, boolean publish) throws XmlRpcException { + // logger.info("metaWeblog.editPost -> postid: {}, post: {}", postid, JSON.toJSONString(post)); + logger.info("metaWeblog.editPost -> postid: {}", postid); + + Map rtnResult = isValid(username, password); + + JSONObject postJson = JSONObject.parseObject(JSON.toJSONString(post)); + // logger.debug("postJson = {}", postJson); + + boolean flag = false; + try { + Post postObj = new Post(); + // ========== + // 数据转换开始 + // ArticleCategory ac = getCategory(postJson.getJSONArray("categories")); + // article.setCategory(ac); + postObj.setId(Integer.valueOf(postid)); + postObj.setTitle(postJson.getString("title")); + postObj.setContent(postJson.getString("description")); + postObj.setTags(postJson.getString("mt_keywords")); + postObj.setName(postJson.getString("wp_slug")); + postObj.setStatus(postJson.getString("post_status")); + postObj.setCreated(postJson.getDate("dateCreated")); + // post page essay note + postObj.setType("post"); + postObj.setAuthorId(1); + // 数据转换结束 + // ========== + + flag = getPostService().savePost(postObj).getId() > 0; + logger.info("flag = {}", flag); + } catch (Exception e) { + e.printStackTrace(); + throw new XmlRpcException(500, e.getMessage()); + } + + return flag; + } + + @Override + public Map getPost(String postid, String username, String password) throws XmlRpcException { + logger.info("metaWeblog.getPost -> postid: {}", postid); + isValid(username, password); + + Map rtnResult = isValid(username, password); + + Map post = new HashMap<>(); + Map pramMap = new HashMap(); + try { + + Post postObj = getPostService().getPostById(Integer.valueOf(postid)); + + // ========== + // 数据转换开始 + // ArticleCategory ac = getCategory(postJson.getJSONArray("categories")); + // article.setCategory(ac); + post.put("title", postObj.getTitle()); + post.put("description", postObj.getContent()); + // article.setKeywords(postJson.getString("mt_keywords")); + post.put("wp_slug", postObj.getName()); + post.put("post_status", postObj.getStatus()); + post.put("dateCreated", postObj.getCreated()); + // post page essay note + post.put("post", postObj.getType()); + // 数据转换结束 + // ========== + } catch (Exception e) { + e.printStackTrace(); + throw new XmlRpcException(500, e.getMessage()); + } + + return post; + } + + @Override + public List> getCategories(String blogid, String username, String password) throws XmlRpcException { + logger.info("metaWeblog.getCategories -> blogid: {}", blogid); + + return new ArrayList<>(); + } + + @Override + public List> getRecentPosts(String blogid, String username, String password, int numberOfPosts) throws XmlRpcException { + logger.info("metaWeblog.getRecentPosts -> blogid: {}, numberOfPosts: {}", blogid, numberOfPosts); + +// Object bean = SpringBeanUtils.getBean("com.terwergreen.plugins.blog.service.impl.PostServiceImpl"); +// Map pramMap = new HashMap(); +// Object posts = ReflectUtil.invoke(bean, "getRecentPosts", new Class[]{Map.class}, new Object[]{pramMap}); +// System.out.println("posts = " + posts); + + return null; + } + + @Override + public Map newMediaObject(String blogid, String username, String password, Map post) throws XmlRpcException { + logger.info("metaWeblog.newMediaObject -> blogid: {}", blogid); + + isValid(username, password); + + Map urlData = new HashMap<>(); + + try { + String retUrl = "http://oss.terwergreen.com/%s"; + String name = post.get("name").toString(); + // {year}/{mon}/{day}/{filename}{.suffix} + Date now = new Date(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd"); + String forder = sdf.format(now); + System.out.println("forder = " + forder); + String fileName = "bugucms/" + forder + "/" + name; + String url = String.format(retUrl, fileName); + + byte[] bits = (byte[]) post.get("bits"); + logger.info("准备上传图片,url = " + url); + // 开始上传图片 + OssManager manager = OssManager.getInstance(); + manager.upload(fileName, bits); + + // 水印 + // String watermark = String.format("?x-oss-process=%s", "image/auto-orient,1/quality,q_90/format,jpg/watermark,image_YnVndWNtcy9sb2dvLWRhcmsucG5nP3gtb3NzLXByb2Nlc3M9aW1hZ2UvcmVzaXplLFBfNjI,g_se,x_10,y_10"); + // String markedUrl = url + watermark; + + urlData.put("url", url); + } catch (Exception e) { + e.printStackTrace(); + logger.error("图片上传错误", e); + } + + logger.info("urlData = {}", urlData); + return urlData; + } +} diff --git a/jvue-server/src/main/java/com/terwergreen/jvueserver/util/SpringBeanUtils.java b/jvue-server/src/main/java/com/terwergreen/jvueserver/util/SpringBeanUtils.java new file mode 100644 index 0000000..5ff2f42 --- /dev/null +++ b/jvue-server/src/main/java/com/terwergreen/jvueserver/util/SpringBeanUtils.java @@ -0,0 +1,42 @@ +package com.terwergreen.jvueserver.util; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.ApplicationContext; + +/** + * ApplicaitonContext工具类 + * + * @name: ApplicationContextUtils + * @author: terwer + * @date: 2022-03-07 14:26 + **/ +public class SpringBeanUtils { + private static final Logger logger = LoggerFactory.getLogger(SpringBeanUtils.class); + + private static ApplicationContext context; + + /** + * 设置上下文:注意,用户不能直接调用,只能由框架启动设置 + * + * @param applicationContext + */ + public static void setContext(ApplicationContext applicationContext) { + final String callee = Thread.currentThread().getStackTrace()[2].getClassName() + + Thread.currentThread().getStackTrace()[1].getMethodName(); // This gets me the caller + logger.debug("SpringBeanUtils setContext callee = " + callee); + if (!"com.terwergreen.jvueserver.JVueServerApplicationsetContext".equals(callee)) { + logger.error("用户不能直接调用,只能由框架启动设置"); + return; + } + context = applicationContext; + } + + public static Object getBean(String beanName) { + return context.getBean(beanName); + } + + public static T getBean(Class t) { + return context.getBean(t); + } +} diff --git a/jvue-server/src/main/resources/mappers/spl-mapping-post.xml b/jvue-server/src/main/resources/mappers/spl-mapping-post.xml index 2be4c03..6d884fb 100644 --- a/jvue-server/src/main/resources/mappers/spl-mapping-post.xml +++ b/jvue-server/src/main/resources/mappers/spl-mapping-post.xml @@ -80,6 +80,9 @@ ,content + + ,name + ,tags @@ -104,6 +107,9 @@ ,#{content} + + ,#{name} + ,#{tags} @@ -127,6 +133,9 @@ content = #{content}, + + name = #{name}, + type = #{type}, diff --git a/jvue-server/src/main/resources/org/apache/xmlrpc/webserver/XmlRpcServlet.properties b/jvue-server/src/main/resources/org/apache/xmlrpc/webserver/XmlRpcServlet.properties new file mode 100644 index 0000000..69717e7 --- /dev/null +++ b/jvue-server/src/main/resources/org/apache/xmlrpc/webserver/XmlRpcServlet.properties @@ -0,0 +1,2 @@ +blogger=com.terwergreen.jvueserver.coresevice.xmlrpc.MetaWeblogImpl +metaWeblog=com.terwergreen.jvueserver.coresevice.xmlrpc.MetaWeblogImpl \ No newline at end of file From d463eb678d7fd781e5ae45f855b8d8b59d0d6b9f Mon Sep 17 00:00:00 2001 From: terwer Date: Mon, 20 Jun 2022 01:53:07 +0800 Subject: [PATCH 6/6] fix:Aliyun oss support --- .../jvueserver/coresevice/aliyunoss/OssManager.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/jvue-server/src/main/java/com/terwergreen/jvueserver/coresevice/aliyunoss/OssManager.java b/jvue-server/src/main/java/com/terwergreen/jvueserver/coresevice/aliyunoss/OssManager.java index 7f1aa29..6117341 100644 --- a/jvue-server/src/main/java/com/terwergreen/jvueserver/coresevice/aliyunoss/OssManager.java +++ b/jvue-server/src/main/java/com/terwergreen/jvueserver/coresevice/aliyunoss/OssManager.java @@ -21,10 +21,10 @@ public class OssManager { private static final Logger logger = LoggerFactory.getLogger(OssManager.class); - private static final String ENDPOINT = "http://oss-cn-qingdao.aliyuncs.com"; - private static final String ACCESS_KEY = "I2qcXHrK0sU1cM26"; - private static final String ACCESS_SECRET = "APQh3jSW1reSJcgAPY7pqVKFOPVJM4"; - private static final String BUCKET_NAME = "terwer"; + private static final String ENDPOINT = "${ALIYUN_OSS_ENDPOINT}"; + private static final String ACCESS_KEY = "${ALIYUN_OSS_ACCESS_KEY}"; + private static final String ACCESS_SECRET = "${ALIYUN_OSS_ACCESS_SECRET}"; + private static final String BUCKET_NAME = "${ALIYUN_OSS_BUCKET_NAME}"; private static OSS client = null;