<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>全部文章 on 庞玉栋个人博客</title><link>https://pangyd.com/post/</link><description>Recent content in 全部文章 on 庞玉栋个人博客</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Sat, 19 Sep 2026 21:35:59 +0800</lastBuildDate><atom:link href="https://pangyd.com/post/index.xml" rel="self" type="application/rss+xml"/><item><title>比亚迪第二代腾势 D9 车型 OTA 升级，AI 超级智能体“迪迪虾”上新</title><link>https://pangyd.com/post/radar-477/</link><pubDate>Sat, 19 Sep 2026 21:35:59 +0800</pubDate><guid>https://pangyd.com/post/radar-477/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>原文&lt;/strong>：&lt;a href="https://www.ithome.com/1/004/561.htm">比亚迪第二代腾势 D9 车型 OTA 升级，AI 超级智能体“迪迪虾”上新&lt;/a>&lt;/p>
&lt;p>&lt;strong>来源&lt;/strong>：IT之家（科技）&lt;/p>
&lt;/blockquote>
&lt;h2 id="正文">正文&lt;/h2>
&lt;p>感谢IT之家网友 华南吴彦祖 的线索投递！&lt;/p>
&lt;p>IT之家 9 月 19 日消息，比亚迪第二代腾势 D9 OTA 于近日焕新升级，AI 超级智能体“迪迪虾”上新。&lt;/p>
&lt;p>IT之家整理如下：&lt;/p>
&lt;p>新增迪迪虾智能搭子，焕新上线。一站式解锁五大新功能，支持 7 分屏和全屏设置。&lt;/p>
&lt;p>新增生态智能体服务吃喝玩乐，支持听音乐、刷视频、点外卖、订酒店。&lt;/p>
&lt;p>新增迪迪虾“AI 空间”功能沉浸式陪聊，语音唤醒即刻交互。&lt;/p>
&lt;p>新增迪迪虾“人设”功能，专属智能搭子随心定义。&lt;/p>
&lt;p>新增迪迪虾“技能”功能技能随心搭配，打造专属空间。&lt;/p>
&lt;p>新增迪迪虾“记忆”功能，声纹注册后，记住你的偏好、习惯和重要事项。&lt;/p>
&lt;p>新增导航智能体服务复杂行程，多地点复杂路线轻松规划，路线攻略查询直达导航。&lt;/p>
&lt;p>IT之家注意到，迪迪虾已接入大量生态合作伙伴智能体，覆盖出行、娱乐、生活服务、AI 大模型等多个领域，包括千问大模型、豆包大模型、飞猪旅行、高德地图、COLMO、淘宝闪购、喜马拉雅、QQ 音乐、酷我音乐、酷狗音乐、网易云音乐、元神小剧、支付宝、爱奇艺、优酷、哔哩哔哩。&lt;/p>
&lt;p>投诉水文&lt;/p>
&lt;p>我要纠错&lt;/p>
&lt;p>下载IT之家APP，签到赚金币兑豪礼&lt;/p>
&lt;p>相关文章&lt;/p>
&lt;p>关键词：腾势 D9，比亚迪，迪迪虾&lt;/p>
&lt;hr>
&lt;blockquote>
&lt;p>由「前沿雷达」于 2026-09-20 采集。正文取自原文页面，已保留出处链接。标题与正文版权归原作者所有。&lt;/p>
&lt;/blockquote></description></item><item><title>“留给人类阻止AI的时间不多了”</title><link>https://pangyd.com/post/radar-161/</link><pubDate>Sat, 19 Sep 2026 19:53:12 +0800</pubDate><guid>https://pangyd.com/post/radar-161/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>原文&lt;/strong>：&lt;a href="https://www.qbitai.com/2026/09/492755.html">“留给人类阻止AI的时间不多了”&lt;/a>&lt;/p>
&lt;p>&lt;strong>作者&lt;/strong>：henry&lt;/p>
&lt;p>&lt;strong>来源&lt;/strong>：量子位（AI 媒体）&lt;/p>
&lt;/blockquote>
&lt;h2 id="正文">正文&lt;/h2>
&lt;p>AI有可能终结我们所有人&lt;/p>
&lt;p>henry 发自 凹非寺&lt;/p>
&lt;p>量子位 | 公众号 QbitAI&lt;/p>
&lt;p>“我坚信，AI有可能终结我们所有人，而留给我们阻止这一结局发生的时间，或许已经不多了。”&lt;/p>
&lt;p>说出这句话的，是不久前从Google DeepMind离职的AI安全研究员Bilal Chughtai。&lt;/p>
&lt;p>自2021年从剑桥大学数学专业毕业以后，Chughtai逐渐将研究重心转向AI，并于2022年初进入这一领域，关注安全、对齐和机制可解释性。&lt;/p>
&lt;p>此后的四年里，他一路从研究神经网络内部机制，到追踪模型欺骗、研究如何识别AI是否在“撒谎”，再到加入Google DeepMind继续做AGI安全与可解释性研究，几乎一直待在AI安全研究的一线。&lt;/p>
&lt;p>也正是在这四年间，他（和我们）亲眼见证了AI能力的飞速变化～&lt;/p>
&lt;p>在离职帖中，Chughtai回忆，2022年刚入行时，AI还只是个“几乎没什么用”的东西；而今年，它已经能攻克困扰人类上百年的数学难题，并开始不受控制，主动攻击Hugging Face系统。&lt;/p>
&lt;p>可以说，这份超越预期的能力进步，在带给Chughtai惊喜的同时，也成为了他离职谷歌，在推特上打出“我坚信，AI有可能杀死我们所有人”的理由。&lt;/p>
&lt;p>目前，这条帖子在X上已经获得超过80万次浏览，并引来彭博等媒体跟进报道。&lt;/p>
&lt;p>可以说，相比于Dario、奥特曼、马斯克等巨头掌舵者的风险表态，Chughtai这样的研发人员，让这场关于人类未来的宏大争论，落回了一个个具体的人身上。&lt;/p>
&lt;p>他们把时间、才华和对未来的期待，投入到一行行代码、一次次实验中，亲手推动AI走到今天。&lt;/p>
&lt;p>如今，这些离技术最近的人，开始在自己参与创造的未来面前感到不安。&lt;/p>
&lt;p>Chughtai并非孤例，面对AI的巨大潜力与失控风险，越来越多一线研发人员开始公开讲述自己的不安，以及继续留下或转身离开的理由。&lt;/p>
&lt;p>9月9日，研究员*Jacob Coxon发帖宣布从Anthropic离职，并直接点名两家前东家：&lt;/p>
&lt;p>OpenAI和Anthropic都没有负责任地行事。它们正一路冲向能够自我改进的超级智能，拿所有人的生命冒险。&lt;/p>
&lt;p>发布后，这条帖子迅速走红网络，截至目前已有1.71亿次浏览，不仅引来多家媒体报道，也得到了OpenAI、Anthropic乃至官方层面的回应。&lt;/p>
&lt;p>能掀起这么大的波澜，人们很容易以为，发声的是某位行业大佬。但事实上，Jacob今年才27岁，而这，甚至是他发出的第一条推文。&lt;/p>
&lt;p>1999年出生的Jacob，曾两次代表英国参加国际数学奥林匹克，分别在2016年和2017年获得银牌、铜牌。&lt;/p>
&lt;p>在剑桥大学完成数学学业后，他先后加入OpenAI和Anthropic，从事预训练研究。GPT-4o的贡献者名单中，就有他的名字。&lt;/p>
&lt;p>和许多投身AI的年轻研究员一样，Jacob曾努力让AI变得更强。如今，他却开始担心，人类会因此失去控制。&lt;/p>
&lt;p>在离职帖中，Jacob特别强调，行业内部一些人对AI可能毁灭人类的担忧是认真的。他们私下表达的恐惧，甚至比公开场合更加强烈。&lt;/p>
&lt;p>但意识到危险，并没有让这场竞赛慢下来。&lt;/p>
&lt;p>在他看来，OpenAI内部的许多人，还没有真正理解这项技术所牵涉的文明层面的风险；Anthropic更清楚其中的危险，却同样被竞争推着向前：如果自己不率先造出超级智能，就会有一家更不负责任的公司抢先做到。&lt;/p>
&lt;p>当每家公司都相信，只有自己赢了，未来才会更安全，继续加速就总能找到理由。&lt;/p>
&lt;p>于是，Jacob决定先让自己停下来，暂时离开前沿AI实验室。&lt;/p>
&lt;p>很快，这份声明得到了Anthropic对齐研究负责人的Evan Hubinger的回应。&lt;/p>
&lt;p>Evan表示，他同意Jacob对风险的判断：他们确实认真地相信，AI存在杀死所有人的可能。他个人估计，未来十年内发生这种情况的概率超过10%。&lt;/p>
&lt;p>与此同时，Evan也强调，他相信Anthropic正在尽力。但对于如何解决超级智能的对齐问题，他们尚未找到方案，也不能确定目前是否正走在通往解决方案的路上。&lt;/p>
&lt;p>可以说，一个人选择离开，另一个人留下继续研究，但对于眼前的风险，两人的判断却有相当程度的重合。&lt;/p>
&lt;p>随后，公司掌舵者也加入了讨论。&lt;/p>
&lt;p>在接受CBS采访时，Dario一方面表达了对Anthropic安全工作的信心，另一方面也强调，解决这些问题，需要科技公司、政府与社会各方共同参与。&lt;/p>
&lt;p>在CNN的采访中，面对关于Jacob的提问，Dario则表示，自己与Jacob的共同意见，远多于分歧。在他看来，Jacob的批评指向了整个行业不断向前竞逐的状态。&lt;/p>
&lt;p>9月12日，Dario发表《We Must Pace the Frontier》一文，明确呼吁放缓AI模型能力提升的速度，为安全研究争取时间。&lt;/p>
&lt;p>这份呼吁随后得到了奥特曼、马斯克等人的公开支持，也将这些一线研究员的不安，带入了更广泛的讨论之中：&lt;/p>
&lt;p>当整个行业都在加速，人类究竟给理解和控制AI，留下了多少时间。&lt;/p>
&lt;p>不过，在另一位一线研究员看来，放慢脚步，可能还不够。&lt;/p>
&lt;p>9月14日，仍在OpenAI工作的Daniel Selsam（下文简称Dan）公开了一份关于AI风险的个人声明。&lt;/p>
&lt;p>有趣的是，Dan甚至没有X账号。这份声明，是请前同事Daniel Kokotajlo代为分享的，后者在介绍中提到，Dan还曾做过自己的上司。&lt;/p>
&lt;p>相比于刚刚离职的Jacob，Dan已经在AI领域工作了十五年之久。&lt;/p>
&lt;p>他在MIT研究过概率编程，在微软研究院参与过Lean定理证明器的早期开发，又在斯坦福攻读博士，探索如何让神经网络学会推理。&lt;/p>
&lt;p>加入OpenAI后，他继续参与思维链优化与预训练研究。在o1推理研究的“奠基贡献者”名单中，就有他的名字，与Ilya Sutskever、Jason Wei、Max Schwarzer、Noam Brow、赵晟佳等大佬共同在列。&lt;/p>
&lt;p>可以说，如何让机器学会思考，贯穿了他的职业生涯。&lt;/p></description></item><item><title>单个机柜到底能跑多少个 Agent？答案不在 GPU 身上</title><link>https://pangyd.com/post/radar-531/</link><pubDate>Sat, 19 Sep 2026 18:55:19 +0800</pubDate><guid>https://pangyd.com/post/radar-531/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>原文&lt;/strong>：&lt;a href="https://www.infoq.cn/article/brH7TRcHB9evl32KQJkY?utm_source=rss&amp;amp;utm_medium=article">单个机柜到底能跑多少个 Agent？答案不在 GPU 身上&lt;/a>&lt;/p>
&lt;p>&lt;strong>作者&lt;/strong>：李文朋&lt;/p>
&lt;p>&lt;strong>来源&lt;/strong>：InfoQ 中国（架构）&lt;/p>
&lt;/blockquote>
&lt;h2 id="正文">正文&lt;/h2>
&lt;p>过去几个月，大厂接连发布了新一代基础模型。Claude Fable 5.1、Gemini 3.8 Flash 与 GPT-6 Astra 等层出不穷。&lt;/p>
&lt;p>不难看出，这些模型几乎都在追求 Agent 的适配能力，让整个推理时间更长，工具调用更顺，决策链条也更稳。&lt;/p>
&lt;p>这也让 Agent 加速进入企业端。数据显示，2026—2027 年，中国企业场景中的活跃智能体（Agent）数量单年同比增长超 200%，到 2031 年预计可达到 3.5 亿个。&lt;/p>
&lt;p>值得注意的是，这种全民狂欢的背后，数据中心正面临巨大的挑战。&lt;/p>
&lt;p>现有数据中心基础设施，基本都是为大模型单次推理调用的吞吐量而设计的，并未真正考虑过 Agent 那种高频、突发、有状态，并且工具调用穿插其中的工作负载。&lt;/p>
&lt;p>谷歌最近的调研提出，近 83% 的企业高管认为基础设施需要为 Agent 时代重新调整。前不久，AMD 也表示 CPU 和 GPU 的配比要重新调整；8 月，AWS 和 NVIDIA 更是宣布，要联手搞下一代 AI 基础设施。&lt;/p>
&lt;p>然而，这些说法更多是围绕输入端的能力参数——比如有多少核心、多少带宽、在功率上限下能运行多少节点。&lt;/p>
&lt;p>英特尔在 8 月发布的一份白皮书中，却表明了不同的立场。英特尔提出，对数据中心进行优化的关键，并不在于提升理论参数值，而是考虑它在实际应用场景下，满足延迟承诺时，能够维持多少 Agent 的任务量。&lt;/p>
&lt;p>一句话说就是：“去计算数据中心的实际工作量，而不是理论的性能上限。”&lt;/p>
&lt;p>这是一个系统级的论点。对于还在摸索 Agent 生产到底需要什么基础设施的行业来说，不失为值得认真对待的思路。&lt;/p>
&lt;p>预告：在 9 月 22 日～23 日，英特尔将会在苏州举办 2026 年 Intel Connection 大会，会上会展示最新的 DCG 产品，以及面向企业 AI 应用落地场景的对应产品。那里或许也有行业所寻求的解决方案。&lt;/p></description></item><item><title>中国电信开源首个全栈国产轻量级智能体大模型 Xing4.0-29B-A4B</title><link>https://pangyd.com/post/radar-494/</link><pubDate>Sat, 19 Sep 2026 18:33:14 +0800</pubDate><guid>https://pangyd.com/post/radar-494/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>原文&lt;/strong>：&lt;a href="https://www.ithome.com/1/004/530.htm">中国电信开源首个全栈国产轻量级智能体大模型 Xing4.0-29B-A4B&lt;/a>&lt;/p>
&lt;p>&lt;strong>来源&lt;/strong>：IT之家（科技）&lt;/p>
&lt;/blockquote>
&lt;h2 id="正文">正文&lt;/h2>
&lt;p>IT之家 9 月 19 日消息，中国电信于 9 月 17 日发布新一代星辰大模型 Xing4.0-29B-A4B，该模型总参数量 29B，激活参数仅 4B，原生支持 256K 上下文，可扩展至 512K，是国内首个基于国产算力与国产框架完成训练、面向复杂工程任务深度优化的百亿参数大模型。&lt;/p>
&lt;p>官方表示，从训练芯片到推理部署，全栈国产 —— 昇腾训练、国产框架适配、自研架构、开源生态，一条路走通。&lt;/p>
&lt;p>从 SuperCLUE 评测结果来看，在智能体能力方面，Xing4.0-29B-A4B 得分 93.52，位列第 3 名，与两款头部 Qwen 模型的差距均不足 1 分。&lt;/p>
&lt;p>据介绍，Xing4.0-29B-A4B 通过 4-bit 量化后显存占用降低至 15GB（比 FP16 省约 75%），RTX 3090、RTX 4090 这类 24G 消费级显卡就能本地跑长上下文任务。&lt;/p>
&lt;p>Xing4.0-29B-A4B 延续星辰大模型的开源路线，对主流开源生态做了全面兼容：支持 LLaMA-Factory、MindFormers 等微调架构；适配 SGLang、vLLM、KTransformers 等主流推理框架；Agent 框架对 OpenCode、Claude Code、OpenClaw、Hermes 做了定向适配调优，深度对齐各框架格式规范。&lt;/p>
&lt;p>星辰大模型 Xing4.0-29B-A4B 已上线开源社区，IT之家附相关链接：&lt;/p>
&lt;p>HuggingFace：https://huggingface.co/XingChen-AGI/Xing4.0-29B-A4B&lt;/p>
&lt;p>GitHub：https://github.com/XingChen-AGI/Xing4.0-29B-A4B&lt;/p>
&lt;p>魔搭：https://modelscope.cn/models/XingChen-AGI/Xing4.0-29B-A4B&lt;/p>
&lt;p>Gitee：https://gitee.com/xingchen-agi/xing4.0-29b-a4b&lt;/p>
&lt;p>魔乐：https://modelers.cn/models/XingChen-AGI/Xing4.0-29B-A4B&lt;/p>
&lt;p>广告声明：文内含有的对外跳转链接（包括不限于超链接、二维码、口令等形式），用于传递更多信息，节省甄选时间，结果仅供参考，IT之家包含外链的文章均包含本声明。&lt;/p>
&lt;p>投诉水文&lt;/p>
&lt;p>我要纠错&lt;/p>
&lt;p>下载IT之家APP，签到赚金币兑豪礼&lt;/p>
&lt;hr>
&lt;blockquote>
&lt;p>由「前沿雷达」于 2026-09-20 采集。正文取自原文页面，已保留出处链接。标题与正文版权归原作者所有。&lt;/p></description></item><item><title>华为全联接大会2026：360与昇腾AI联合打造解决方案，为AI Agent全面提速</title><link>https://pangyd.com/post/radar-172/</link><pubDate>Sat, 19 Sep 2026 09:58:00 +0800</pubDate><guid>https://pangyd.com/post/radar-172/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>原文&lt;/strong>：&lt;a href="https://www.leiphone.com/category/industrynews/uKmCBjBhfQW9iDHy.html">华为全联接大会2026：360与昇腾AI联合打造解决方案，为AI Agent全面提速&lt;/a>&lt;/p>
&lt;p>&lt;strong>来源&lt;/strong>：雷锋网（AI 媒体）&lt;/p>
&lt;/blockquote>
&lt;h2 id="正文">正文&lt;/h2>
&lt;p>2026年9月17日，第十一届华为全联接大会在上海开幕。大会期间，360集团与昇腾AI联合打造解决方案。以360智能体工厂为核心的智能体基础设施与昇腾AI深度协同，面向AI Agent场景实现全面提速，为复杂任务执行、多智能体协作和长链路推理提供更高效、更稳定的底层支撑。这也是双方继2026世界人工智能大会联合展示后，合作成果的进一步深化落地。&lt;/p>
&lt;p>图说：华为全联接大会期间360与昇腾AI展台&lt;/p>
&lt;p>作为360智能体基础设施的核心组件，360智能体工厂承担智能体生成与编排职能，支持通过自然语言快速生成智能体并组建多智能体协作蜂群。其首创的“蜂群多智能体协作技术”支持多智能体多层嵌套、灵活组队与共享协作记忆，实现任务自主规划与协同执行，使原本需要2小时的多角色协作任务缩短至20分钟，效率提升6倍。&lt;/p>
&lt;p>随着AI Agent从单轮问答迈向复杂任务执行，异步并行、多智能体协同、长上下文推理以及高频工具调用逐渐成为主流应用形态。Agent运行过程中需要持续进行任务拆解、规划决策、工具调用和结果反馈，这对底层算力平台的稳定性、吞吐能力和响应速度提出了更高要求。&lt;/p>
&lt;p>针对智能体场景中的长序列推理和频繁KV Cache读写等挑战，昇腾AI进行了针对性性能优化，通过长序列优化、吞吐优化、运行时优化及算子优化等能力提升，有效降低首Token时延，提升整体吞吐效率，为高并发、长链路Agent任务提供稳定支撑。&lt;/p>
&lt;p>在深度理解、通用理解和智能体执行等典型场景中，搭载DeepSeek、Qwen、GLM等主流模型时，昇腾AI已具备良好的开箱性能，经过进一步优化后实现整体性能提升。基于昇腾AI算力支撑，360智能体工厂在内测过程中已实现超过1000步复杂任务连续执行不中断，任务成功率达到95%以上。同时，360智能体工厂采用透明化人机协同机制，将智能体的思考过程、任务规划路径和执行状态全程可视化，让用户能够实时掌握任务进展与执行结果，而底层毫秒级响应能力则为这一体验提供了坚实保障。&lt;/p>
&lt;p>图说：360智能体工厂与昇腾AI合作路径示意&lt;/p>
&lt;p>当前，AI产业正从“大模型竞争”逐步走向“智能体竞争”。智能体的价值不仅取决于模型能力，更依赖于模型、工具、工作流与算力基础设施之间的协同效率。此次360与昇腾AI联合打造解决方案，正是智能体基础设施与国产AI算力协同发展的又一次实践探索。&lt;/p>
&lt;p>未来，双方将持续推进智能体基础设施与国产AI算力生态融合创新，为AI Agent规模化应用提供更高效、更稳定的底层支撑，助力更多企业加速迈向AI时代。&lt;/p>
&lt;hr>
&lt;blockquote>
&lt;p>由「前沿雷达」于 2026-09-20 采集。正文取自原文页面，已保留出处链接。标题与正文版权归原作者所有。&lt;/p>
&lt;/blockquote></description></item><item><title>Grab 智能体框架 LLM-Kit 加速 AI 智能体生产部署</title><link>https://pangyd.com/post/radar-534/</link><pubDate>Sat, 19 Sep 2026 02:00:00 +0800</pubDate><guid>https://pangyd.com/post/radar-534/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>原文&lt;/strong>：&lt;a href="https://www.infoq.cn/article/AFC40lL0yaxVCDvBRFOK?utm_source=rss&amp;amp;utm_medium=article">Grab 智能体框架 LLM-Kit 加速 AI 智能体生产部署&lt;/a>&lt;/p>
&lt;p>&lt;strong>作者&lt;/strong>：作者：Hien Luu&lt;/p>
&lt;p>&lt;strong>来源&lt;/strong>：InfoQ 中国（架构）&lt;/p>
&lt;/blockquote>
&lt;h2 id="正文">正文&lt;/h2>
&lt;p>Grab 用 LLM-Kit 对 500 多个内部智能体服务进行了标准化。LLM-Kit 是一个脚手架与集成工具集，可为新建服务直接提供基础智能体执行循环，同时内置评估、链路追踪、密钥管理以及工具服务器连接能力。智能体会在运行时从 50 多个 MCP 服务器中发现可用工具，并通过统一的网关访问模型。因此，新增能力和新增模型服务商只需要进行注册或配置，不需要重新部署。&lt;/p>
&lt;p>现在，在 Grab 把一个全新的 AI 智能体服务接入生产环境大约需要 1 小时，而过去需要两周甚至更久。效率提升的关键点不在于智能体本身的推理循环，而是周围的配套系统：密钥、追踪、服务发现和评估。Grab 在一篇关于 LLM-Kit 的工程博客文章中介绍了这一变化。该框架目前为这家东南亚网约车和外卖公司的 500 多个服务提供支撑，其中包括每天被数百万商家、司机和消费者使用的智能体。文章写道：“推理循环的开发只花了一个下午，而生产环境适配封装却要两周。”&lt;/p>
&lt;p>LLM-Kit 消除的是每项服务都要单独做技术方案决策的负担。它没有被设计成一种新的智能体抽象或领域特定语言，而是围绕 Grab 已有的基础设施而搭建的脚手架。Grab 的思路发生了转变：不再逐个服务重复解决同类问题，改为集中统一一次性解决所有问题，LLM-Kit 正是在这个思路下搭建而成。工程师填写一个表单，就会得到一个 GitLab 代码库，里面是一个可运行的 FastAPI 服务，已经内置了 LangGraph Agent 模块、OpenTelemetry 追踪、Vault 密钥管理和服务发现，并且从第一次代码提交开始就带有一个评估端点，可用 ROUGE、BLEU 以及另一个模型作为评分器进行打分。&lt;/p>
&lt;p>图 1：FastAPI 服务项目目录结构（来源：Grab 博客）&lt;/p>
&lt;p>工具并不是预先绑定好的：智能体会在运行时从 50 多个已注册、支持 Model Context Protocol 的服务器中获取工具。因此，一项能力只需注册一次就能被所有智能体使用。模型服务商同样不是预先接好的。每一次模型调用都会经过兼容 OpenAI 接口的 GrabGPT Gateway。该网关前置接入了五家服务商，并注入凭证，因此应用代码永远不会硬编码某个服务商的信息。&lt;/p>
&lt;p>选择框架而不是平台，是有意为之。文章解释了原因：&lt;/p>
&lt;p>平台会将团队束缚在固化的预设方案中，而这些方案很快就会过时。采用框架的形式则可以适配开发者现有的工作方式。&lt;/p>
&lt;p>分析师 Kai Waehner 曾在今年 4 月份提出，”Agentic AI 的技术锁定比 API 锁定更持久，因为它会同时在多个层面累积。“他提到的层面包括模型、框架、运行时，以及团队基于这些组件搭建出来的开发范式。他的文章并非针对 Grab，但这个分析框架同样适用：网关覆盖的是模型层，而框架、运行时与开发范式则很难封装到单一接口背后，并且是 LLM-Kit 上所有服务共用的部分。&lt;/p></description></item><item><title>别再让 Agent 裸连数据库了：如何用 MCP + 语义网关解决 NL2SQL 幻觉与权限失控</title><link>https://pangyd.com/post/radar-400/</link><pubDate>Fri, 18 Sep 2026 20:54:57 +0800</pubDate><guid>https://pangyd.com/post/radar-400/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>原文&lt;/strong>：&lt;a href="https://www.oschina.net/news/502591">别再让 Agent 裸连数据库了：如何用 MCP + 语义网关解决 NL2SQL 幻觉与权限失控&lt;/a>&lt;/p>
&lt;p>&lt;strong>来源&lt;/strong>：开源中国（资讯）&lt;/p>
&lt;/blockquote>
&lt;h2 id="摘要">摘要&lt;/h2>
&lt;p>在 2026 年，给 AI Agent（Cursor、Claude Desktop、Dify、Coze 等）外挂一个数据库连接，已经成为很多开发者的标配操作。从简单的官方 SQLite/MySQL MCP 到各种通用客户端扩展，让大模型“直接查库”的门槛被降得极低。 然而，一旦进入真实业务场景，大部分团队很快就会撞上两堵高墙： 语义幻觉严重：大模型根本不懂企业&amp;hellip;&lt;/p>
&lt;hr>
&lt;blockquote>
&lt;p>由「前沿雷达」于 2026-09-20 采集。本文为原文摘要（该源未提供可提取的全文），完整内容请点上方「原文」链接。标题与正文版权归原作者所有。&lt;/p>
&lt;/blockquote></description></item><item><title>让 Agent 越用越强：AReaL 2.0 构建 Agent 在线强化学习闭环｜QCon上海</title><link>https://pangyd.com/post/radar-543/</link><pubDate>Fri, 18 Sep 2026 18:00:00 +0800</pubDate><guid>https://pangyd.com/post/radar-543/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>原文&lt;/strong>：&lt;a href="https://www.infoq.cn/article/x2FmIeCkeDYUV66BNj3g?utm_source=rss&amp;amp;utm_medium=article">让 Agent 越用越强：AReaL 2.0 构建 Agent 在线强化学习闭环｜QCon上海&lt;/a>&lt;/p>
&lt;p>&lt;strong>作者&lt;/strong>：QCon全球软件开发大会&lt;/p>
&lt;p>&lt;strong>来源&lt;/strong>：InfoQ 中国（架构）&lt;/p>
&lt;/blockquote>
&lt;h2 id="正文">正文&lt;/h2>
&lt;p>从「构建 AI」到「驾驭 AI」，100+ 实战案例拆解 AI Native 时代的工程新实践！&lt;/p>
&lt;p>推理模型持续突破能力边界，Coding Agent 深度参与研发流程，Agent Runtime、Agent Framework 快速演进……AI 正在从回答问题的模型，演变为能够自主规划、调用工具、执行任务的软件系统。AI 不再只是软件中的一个能力，而开始成为软件系统的一部分。这意味着软件工程面对的挑战也发生了变化：团队需要思考的不再只是如何训练模型、模型、部署模型 或优化 Prompt，而不是如何让具备自主能力的 AI 稳定、可信、可控地运行。模型决定 AI 能做什么，系统决定 AI 能否真正创造价值。&lt;/p>
&lt;p>在这一背景下，2026 年 QCon 全球软件开发大会大会 · 上海站正式启动。本次大会将于 10 月 22 日—24 日举办，聚焦 Harness AI 时代的工程实践，围绕 AI Native 架构、Agent Runtime、AI Infra、Data Systems、Agent 安全与可观测、Loop Engineering、Vibe Coding、具身智能与世界模型、端云协同等前沿技术方向，邀请全球技术社区与产业一线的实践者，系统性分享前沿洞察与实战经验，共同探索 AI 从能力到系统、从实验到生产的真实路径。&lt;/p>
&lt;p>香港科技大学助理教授袁彬航博士已确认出席 “AI Infra：算力效率决定规模化落地” 专题，并发表题为《让 Agent 越用越强：AReaL 2.0 构建 Agent 在线强化学习闭环》的主题分享。随着 Coding Agent、企业智能助手等 Agent 应用进入真实生产环境，如何让 Agent 在持续使用过程中不断提升能力，成为下一阶段的重要挑战。传统 Agent 系统产生的大量交互轨迹、工具调用记录和用户反馈通常仅用于日志分析，难以转化为模型能力提升的数据闭环。本次分享介绍 AReaL 2.0 如何构建面向 Agent 自演进的在线强化学习基础设施。方案通过 Agent 轨迹协议、数据代理层和演进控制平面，将真实业务交互转化为可训练、可回放、可治理的数据，并通过微服务化 Agent-Compute 架构，实现无需重构原有 Agent 即可接入 Online RL。在 Hermes Agent 和软件工程 Agent 场景中，该方案支持大规模并发环境、异步训练和持续优化，使 Agent 从“一次性执行系统”逐步演进为“持续学习系统”。&lt;/p></description></item><item><title>仅用3天！千问办公协助国家天文台科研团队打造科研级望远镜仿真系统</title><link>https://pangyd.com/post/radar-179/</link><pubDate>Fri, 18 Sep 2026 14:24:00 +0800</pubDate><guid>https://pangyd.com/post/radar-179/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>原文&lt;/strong>：&lt;a href="https://www.leiphone.com/category/industrynews/HlXq3tJy48q1NubA.html">仅用3天！千问办公协助国家天文台科研团队打造科研级望远镜仿真系统&lt;/a>&lt;/p>
&lt;p>&lt;strong>来源&lt;/strong>：雷锋网（AI 媒体）&lt;/p>
&lt;/blockquote>
&lt;h2 id="摘要">摘要&lt;/h2>
&lt;p>日前，千问办公协助国家天文台科研团队打造大口径科研级望远镜数字化仿真系统，耗时仅3天，成本不到千元。依托对真实望远镜组件和观测条件的模拟，Agent可在仿真环境中驱动望远镜进行远程态势感知与观测流程仿真。未来，仿真系统产生的数据，还将用于训练望远镜控制模型（VLA）中。&lt;/p>
&lt;p>据介绍，超新星爆发、伽马暴等瞬变事件是研究宇宙演化和极端物理过程的重要窗口，但它们出现时间难以预测。与此同时，科研级望远镜资源有限，真实设备难以承担大量试错。因此，在正式观测前，科研团队通常需要先搭建望远镜仿真系统，完整模拟观测流程，验证方案可行性后，再应用于真实设备。过去，这类仿真系统通常依赖软件供应商开发，需要约三个月，成本高达数万元。&lt;/p>
&lt;p>千问办公协助国家天文台相关科研团队搭建大口径科研级望远镜数字化仿真系统，并将望远镜各组件、传感器状态及观测环境信息整合为标准MCP接口，供Agent监测与调用。在仿真环境中，跨巡天对齐时序模型可以从多巡天公开数据中识别极早期超新星候选，让Agent知道“看什么”；短时局部气象预测模型能够综合云量、风速和湿度等实时参数评估观测条件，让Agent 理解“怎么看”。最终，Agent可以进一步综合科学目标优先级、望远镜实时状态以及目标可观测窗口，自主完成“状态感知——任务规划——方案生成——流程验证”的闭环。&lt;/p>
&lt;p>目前，该Agent框架已接入“司天”探路者和“司天”原型机。科研人员提出科学观测需求后，智能体结合目标优先级、天气和设备状态生成观测方案，通过不同MCP接口调用相应控制模块，并将观测结果反馈给科研人员；任务结束后，还可以根据执行结果和专家反馈重新规划后续任务，并将有效经验沉淀为可复用的Skill。截至目前，相关Agent已经预警8颗极早期超新星候选，其中2颗在天气条件允许的情况下触发了后续观测。&lt;/p>
&lt;p>更值得关注的是，此次不仅是针对单一望远镜提供的仿真系统，也是对新的天文科研组织和执行方式的探索。&lt;/p>
&lt;p>过去，望远镜自动化系统主要按照预先设定的流程运行；当天气、设备状态或者科学目标发生变化时，仍需要科研人员人工判断和调整。随着大模型、Agent、科学模型和望远镜控制系统逐步连接，AI开始具备根据实时环境和科学目标进行动态规划、调用工具、验证方案并调整观测策略的能力。&lt;/p>
&lt;p>同时，仿真系统还可以在虚拟环境中反复执行观测任务，持续记录设备状态、环境变化、决策过程和执行结果，形成面向望远镜智能控制的高质量训练数据，为进一步训练望远镜控制模型（VLA），以及未来在真实科学装置上实现更高水平的智能观测奠定基础。&lt;/p>
&lt;p>“科研范式正在发生改变：AI 在科研中的角色不再只是辅助分析，而是进一步进入科研执行流程本身。科研工作者更多负责提出问题、设定目标，智能体则承担观测执行、验证和迭代工作。”国家天文台人工智能推进委员会专家李瑀旸博士表示。&lt;/p>
&lt;hr>
&lt;blockquote>
&lt;p>由「前沿雷达」于 2026-09-20 采集。本文为原文摘要（该源未提供可提取的全文），完整内容请点上方「原文」链接。标题与正文版权归原作者所有。&lt;/p>
&lt;/blockquote></description></item><item><title>StageGuard: Learning Stage Transitions for Long-Horizon Robot Tasks via Agentic Distillation</title><link>https://pangyd.com/post/radar-320/</link><pubDate>Fri, 18 Sep 2026 01:53:48 +0800</pubDate><guid>https://pangyd.com/post/radar-320/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>原文&lt;/strong>：&lt;a href="https://arxiv.org/abs/2609.20791v1">StageGuard: Learning Stage Transitions for Long-Horizon Robot Tasks via Agentic Distillation&lt;/a>&lt;/p>
&lt;p>&lt;strong>作者&lt;/strong>：Jinbang Huang, Yuanzhao Hu, Zhiyuan Li, Ran Qi, Yixin Xiao, Yangzheng Wu, Tengyue Ba, Zhanguang Zhang, Yingxue Zhang&lt;/p>
&lt;p>&lt;strong>来源&lt;/strong>：arXiv cs.RO（机器人）&lt;/p>
&lt;/blockquote>
&lt;h2 id="正文">正文&lt;/h2>
&lt;p>Computer Science &amp;gt; Robotics&lt;/p>
&lt;p>arXiv:2609.20791v1 (cs)&lt;/p>
&lt;p>[Submitted on 17 Sep 2026]&lt;/p>
&lt;p>Title:StageGuard: Learning Stage Transitions for Long-Horizon Robot Tasks via Agentic Distillation&lt;/p>
&lt;p>Authors:Jinbang Huang, Yuanzhao Hu, Zhiyuan Li, Ran Qi, Yixin Xiao, Yangzheng Wu, Tengyue Ba, Zhanguang Zhang, Yingxue Zhang&lt;/p></description></item><item><title>Large Language Models as Falsifiers for Cyber-Physical Systems</title><link>https://pangyd.com/post/radar-14/</link><pubDate>Fri, 18 Sep 2026 01:40:04 +0800</pubDate><guid>https://pangyd.com/post/radar-14/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>原文&lt;/strong>：&lt;a href="https://arxiv.org/abs/2609.20752v1">Large Language Models as Falsifiers for Cyber-Physical Systems&lt;/a>&lt;/p>
&lt;p>&lt;strong>作者&lt;/strong>：Ali ArjomandBigdeli, Jiawei Zhou, Stanley Bak&lt;/p>
&lt;p>&lt;strong>来源&lt;/strong>：arXiv cs.AI（人工智能）&lt;/p>
&lt;/blockquote>
&lt;h2 id="正文">正文&lt;/h2>
&lt;p>Electrical Engineering and Systems Science &amp;gt; Systems and Control&lt;/p>
&lt;p>arXiv:2609.20752v1 (eess)&lt;/p>
&lt;p>[Submitted on 17 Sep 2026]&lt;/p>
&lt;p>Title:Large Language Models as Falsifiers for Cyber-Physical Systems&lt;/p>
&lt;p>Authors:Ali ArjomandBigdeli, Jiawei Zhou, Stanley Bak&lt;/p>
&lt;p>View a PDF of the paper titled Large Language Models as Falsifiers for Cyber-Physical Systems, by Ali ArjomandBigdeli and 2 other authors&lt;/p>
&lt;p>View PDF&lt;/p></description></item><item><title>MoWAM: Explicit Future Motion Prediction for Efficient World Action Models</title><link>https://pangyd.com/post/radar-324/</link><pubDate>Fri, 18 Sep 2026 01:07:00 +0800</pubDate><guid>https://pangyd.com/post/radar-324/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>原文&lt;/strong>：&lt;a href="https://arxiv.org/abs/2609.20709v1">MoWAM: Explicit Future Motion Prediction for Efficient World Action Models&lt;/a>&lt;/p>
&lt;p>&lt;strong>作者&lt;/strong>：Jiayu Wang, Bin Zhu, Yue Yu, Jingjing Chen&lt;/p>
&lt;p>&lt;strong>来源&lt;/strong>：arXiv cs.RO（机器人）&lt;/p>
&lt;/blockquote>
&lt;h2 id="正文">正文&lt;/h2>
&lt;p>Computer Science &amp;gt; Robotics&lt;/p>
&lt;p>arXiv:2609.20709v1 (cs)&lt;/p>
&lt;p>[Submitted on 17 Sep 2026]&lt;/p>
&lt;p>Title:MoWAM: Explicit Future Motion Prediction for Efficient World Action Models&lt;/p>
&lt;p>Authors:Jiayu Wang, Bin Zhu, Yue Yu, Jingjing Chen&lt;/p>
&lt;p>View a PDF of the paper titled MoWAM: Explicit Future Motion Prediction for Efficient World Action Models, by Jiayu Wang and 3 other authors&lt;/p></description></item><item><title>Semantic SLAM in Precision Agriculture using Bayesian Inference</title><link>https://pangyd.com/post/radar-333/</link><pubDate>Thu, 17 Sep 2026 23:51:05 +0800</pubDate><guid>https://pangyd.com/post/radar-333/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>原文&lt;/strong>：&lt;a href="https://arxiv.org/abs/2609.20604v1">Semantic SLAM in Precision Agriculture using Bayesian Inference&lt;/a>&lt;/p>
&lt;p>&lt;strong>作者&lt;/strong>：Ruben Beumer, Sander Doodeman, René van de Molengraft, Duarte Antunes&lt;/p>
&lt;p>&lt;strong>来源&lt;/strong>：arXiv cs.RO（机器人）&lt;/p>
&lt;/blockquote>
&lt;h2 id="正文">正文&lt;/h2>
&lt;p>Computer Science &amp;gt; Robotics&lt;/p>
&lt;p>arXiv:2609.20604v1 (cs)&lt;/p>
&lt;p>[Submitted on 17 Sep 2026]&lt;/p>
&lt;p>Title:Semantic SLAM in Precision Agriculture using Bayesian Inference&lt;/p>
&lt;p>Authors:Ruben Beumer, Sander Doodeman, René van de Molengraft, Duarte Antunes&lt;/p>
&lt;p>View a PDF of the paper titled Semantic SLAM in Precision Agriculture using Bayesian Inference, by Ruben Beumer and 2 other authors&lt;/p></description></item><item><title>CoRef-GS: Cooperative Referring Gaussian Splatting for Multi-Agent Scene Understanding</title><link>https://pangyd.com/post/radar-124/</link><pubDate>Thu, 17 Sep 2026 23:39:25 +0800</pubDate><guid>https://pangyd.com/post/radar-124/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>原文&lt;/strong>：&lt;a href="https://arxiv.org/abs/2609.20586v1">CoRef-GS: Cooperative Referring Gaussian Splatting for Multi-Agent Scene Understanding&lt;/a>&lt;/p>
&lt;p>&lt;strong>作者&lt;/strong>：Zhikun Zhou, Kunyu Peng, Runyi Yang, Junhao Cai, Di Wen, Ruiping Liu, Danda Pani Paudel, Yi Zhou, Luc Van Gool, Kailun Yang&lt;/p>
&lt;p>&lt;strong>来源&lt;/strong>：arXiv cs.CV（计算机视觉）&lt;/p>
&lt;/blockquote>
&lt;h2 id="正文">正文&lt;/h2>
&lt;p>Computer Science &amp;gt; Robotics&lt;/p>
&lt;p>arXiv:2609.20586v1 (cs)&lt;/p>
&lt;p>[Submitted on 17 Sep 2026]&lt;/p>
&lt;p>Title:CoRef-GS: Cooperative Referring Gaussian Splatting for Multi-Agent Scene Understanding&lt;/p>
&lt;p>Authors:Zhikun Zhou, Kunyu Peng, Runyi Yang, Junhao Cai, Di Wen, Ruiping Liu, Danda Pani Paudel, Yi Zhou, Luc Van Gool, Kailun Yang&lt;/p></description></item><item><title>Language-model groups overstate consensus when replaying human deliberation on a reasoning task</title><link>https://pangyd.com/post/radar-27/</link><pubDate>Thu, 17 Sep 2026 23:11:08 +0800</pubDate><guid>https://pangyd.com/post/radar-27/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>原文&lt;/strong>：&lt;a href="https://arxiv.org/abs/2609.20543v1">Language-model groups overstate consensus when replaying human deliberation on a reasoning task&lt;/a>&lt;/p>
&lt;p>&lt;strong>作者&lt;/strong>：Tengfei Shao&lt;/p>
&lt;p>&lt;strong>来源&lt;/strong>：arXiv cs.AI（人工智能）&lt;/p>
&lt;/blockquote>
&lt;h2 id="正文">正文&lt;/h2>
&lt;p>Computer Science &amp;gt; Artificial Intelligence&lt;/p>
&lt;p>arXiv:2609.20543v1 (cs)&lt;/p>
&lt;p>[Submitted on 17 Sep 2026]&lt;/p>
&lt;p>Title:Language-model groups overstate consensus when replaying human deliberation on a reasoning task&lt;/p>
&lt;p>Authors:Tengfei Shao&lt;/p>
&lt;p>View a PDF of the paper titled Language-model groups overstate consensus when replaying human deliberation on a reasoning task, by Tengfei Shao&lt;/p>
&lt;p>View PDF&lt;/p>
&lt;p>Abstract:Full-consensus rates are often treated as indicators of collective cognition, yet depend on how participation and final states are operationalized. We replayed 100 held-out human Wason groups with matched large language model (LLM) agent groups, seeding one belief-anchored agent per participant&amp;rsquo;s pre-discussion answer and scoring agents and people with the same code. Across human scoring definitions, estimates ranged from 24.0% to 57.0%; about one fifth of participants never posted, whereas agents almost always did. Agent groups remained more consensual in two post-unblinding sensitivity analyses: the submit-based comparison (n = 98) yielded gaps of 34.0 and 43.9 percentage points for chat and reasoning modes, and the participation-matched comparison (n = 45) yielded gaps of 34.1 and 44.4 points. These complementary routes reduced different measurement asymmetries yet converged within 0.5 percentage points. The gap persisted without early stopping and under a reparameterization removing the memorizable answer; reasoning-mode groups then agreed nearly unanimously, mostly on incorrect answers. Simulated consensus did not track collective accuracy, and belief-anchored agent groups were biased estimators of the human group-outcome distribution in this setting. These analyses provide a scoring-explicit basis for assessing simulated-group estimates of human deliberative outcomes.&lt;/p></description></item><item><title>Parallelism, critical windows, and separations among diffusion language models</title><link>https://pangyd.com/post/radar-376/</link><pubDate>Thu, 17 Sep 2026 23:10:18 +0800</pubDate><guid>https://pangyd.com/post/radar-376/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>原文&lt;/strong>：&lt;a href="https://arxiv.org/abs/2609.20539v1">Parallelism, critical windows, and separations among diffusion language models&lt;/a>&lt;/p>
&lt;p>&lt;strong>作者&lt;/strong>：Sitan Chen, Liye Wang&lt;/p>
&lt;p>&lt;strong>来源&lt;/strong>：arXiv cs.LG（机器学习）&lt;/p>
&lt;/blockquote>
&lt;h2 id="正文">正文&lt;/h2>
&lt;p>Computer Science &amp;gt; Machine Learning&lt;/p>
&lt;p>arXiv:2609.20539v1 (cs)&lt;/p>
&lt;p>[Submitted on 17 Sep 2026]&lt;/p>
&lt;p>Title:Parallelism, critical windows, and separations among diffusion language models&lt;/p>
&lt;p>Authors:Sitan Chen, Liye Wang&lt;/p>
&lt;p>View a PDF of the paper titled Parallelism, critical windows, and separations among diffusion language models, by Sitan Chen and 1 other authors&lt;/p>
&lt;p>View PDF&lt;/p>
&lt;p>HTML (experimental)&lt;/p>
&lt;p>Abstract:A popular selling point of diffusion large language models (dLLMs) is their capacity for parallelism: the ability to generate sequences of text far more efficiently than autoregressive models, which require one forward pass per token. Yet among the many competing paradigms for dLLMs, from masked to uniform to Gaussian diffusion, principled understanding of how these different proposals compare in parallelism remains limited. In this work, we initiate a fine-grained comparison of the capacity for parallelism among these three leading approaches and prove the following:&lt;/p></description></item><item><title>RoboFind: Multi-Agent Personalized Object Search for People Who Are Blind or Have Low Vision</title><link>https://pangyd.com/post/radar-346/</link><pubDate>Thu, 17 Sep 2026 21:04:23 +0800</pubDate><guid>https://pangyd.com/post/radar-346/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>原文&lt;/strong>：&lt;a href="https://arxiv.org/abs/2609.20330v1">RoboFind: Multi-Agent Personalized Object Search for People Who Are Blind or Have Low Vision&lt;/a>&lt;/p>
&lt;p>&lt;strong>作者&lt;/strong>：Ruiping Liu, Shaofang Quan, Qian Yin, Jingqi Zhang, Junwei Zheng, Yufan Chen, Di Wen, Weijia Fan, Kailun Yang, M. Saquib Sarfraz, Tamim Asfour, Kunyu Peng, Rainer Stiefelhagen&lt;/p>
&lt;p>&lt;strong>来源&lt;/strong>：arXiv cs.RO（机器人）&lt;/p>
&lt;/blockquote>
&lt;h2 id="正文">正文&lt;/h2>
&lt;p>Computer Science &amp;gt; Robotics&lt;/p>
&lt;p>arXiv:2609.20330v1 (cs)&lt;/p>
&lt;p>[Submitted on 17 Sep 2026]&lt;/p>
&lt;p>Title:RoboFind: Multi-Agent Personalized Object Search for People Who Are Blind or Have Low Vision&lt;/p>
&lt;p>Authors:Ruiping Liu, Shaofang Quan, Qian Yin, Jingqi Zhang, Junwei Zheng, Yufan Chen, Di Wen, Weijia Fan, Kailun Yang, M. Saquib Sarfraz, Tamim Asfour, Kunyu Peng, Rainer Stiefelhagen&lt;/p></description></item><item><title>九识建成首个L4万卡集群，无人驾驶进入多模态大模型新范式</title><link>https://pangyd.com/post/radar-189/</link><pubDate>Thu, 17 Sep 2026 18:14:00 +0800</pubDate><guid>https://pangyd.com/post/radar-189/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>原文&lt;/strong>：&lt;a href="https://www.leiphone.com/category/industrynews/sOtgTcXitH6C7vAT.html">九识建成首个L4万卡集群，无人驾驶进入多模态大模型新范式&lt;/a>&lt;/p>
&lt;p>&lt;strong>来源&lt;/strong>：雷锋网（AI 媒体）&lt;/p>
&lt;/blockquote>
&lt;h2 id="摘要">摘要&lt;/h2>
&lt;p>一家做无人车的公司，为什么需要一万多张GPU？
9月10日，九识CEO孔旗在广州宣布战略升级为“城市级物理AI”。一周后的9月17日，CTO庄立首次披露支撑这次升级的底层能力：九识已建成业内首个L4级万卡集群，算力集群总规模近1.5万卡。九识也成为首个建成万卡集群的L4团队。
而万卡算力的背后，是一个正在从百亿级迈向千亿级的九识APEX多模态基座大模型。
无人驾驶下半场：迈入多模态大模型新范式
在智能驾驶圈子里，长期存在一个顽固的偏见：载人自动驾驶是高科技，城市货运无人车，AI壁垒更低。但事实显然不是如此。
九识成立于2021年8月，创始团队是中国无人驾驶的拓荒者，曾在百度硅谷研究院主导了Robotaxi、Robotruck的研发工作，并为第一代Appollo开源平台作出了重要贡献。而创业之初，就选择了崭新的领域RoboVan，过去五年，这家企业围绕技术、场景、商业模式三大核心方向深耕布局。
这五年，九识干了三件事：第一件事，把技术真正做出来，发明了全球第一台Robovan；第二件事：让无人驾驶走进更多真实场景，从聚焦物流到L4技术赋能千行百业；第三件事：跑出了无人驾驶的成熟商业范式——卖车、服务、运力。
从2023年卖出第一台车，到如今，九识全球车队超过3万台，覆盖20多个国家、300多座城市，累计真实运营里程超过2.7亿公里。
但规模跑通之后，一个更根本的问题浮出水面：当无人车面对真实城市里那些无法用规则穷尽的大量长尾场景——无标识乡村道路、临时施工围挡、异形障碍物、人车无序混行、恶劣天气光影突变——分水岭到底是什么？
今天，九识从另一个维度回答了这个问题——正式披露其算力集群突破“万卡”规模，成为业内首家建成L4万卡集群的L4无人驾驶企业。
这也意味着无人驾驶开始迈入多模态大模型的新范式。
万卡算力集群，让车拥有“自我进化”的能力
万卡集群，指的是由超过一万张加速卡组成的高性能计算系统，用以训练基础大模型。
单张AI加速卡像一个高速计算单元，万卡集群则像一座由上万台计算设备组成的‘AI超级工厂’，能够把一个复杂的大模型训练任务拆解后并行处理。
更重要的是，算力的层级，将在基础设施上决定一家智驾企业的智能上限。真实的城市货运场景，充满了长尾非标路况，根本无法用人工规则穷尽。
九识的解法是用大模型去学习物理世界，而万卡集群就是训练这些模型的硬性前提。万卡算力集群，是支撑千亿大模型演进的硬核底座。
据九识披露，其APEX多模态基座大模型正在由百亿级参数规模向千亿级迈进。APEX融合了海量真实L4驾驶数据与互联网语言、视频等知识语料和真实运营的人类决策数据，通过APEX 基座训练完成后，向下赋能数据、模型、评测，实现迭代闭环。
万卡集群赋予九识的，是“自我进化”的能力。3万台车、300多座城市、2.7亿公里真实L4运营数据，每天都在喂养这套算力体系。算力越强，模型迭代越快。模型越强，运营成本越低，更多客户愿意用，车跑起来又产生更多稀缺数据。
孔旗说过一句话：“复杂城市开放道路能够产生高价值数据，而商业模式本身需要赚钱，才能持续获取数据、推动技术进步。”算力不是成本，是飞轮的起点。
APEX九识基座世界模型，让车“理解物理世界”
九识此次战略升级的核心，落在“九识大脑”上——它是九识无人车实现服务与城市治理生态的核心基座。而九识大脑的核心，是正从百亿迈入千亿的APEX多模态基座大模型。
APEX赋予九识的，是“理解物理世界的变化”。
这种能力带来四个层面的质变。
场景推理与决策能力更强，具备预测推演能力，长时序博弈预判大幅提升行驶平顺性与安全性。
知…&lt;/p>
&lt;hr>
&lt;blockquote>
&lt;p>本文由「前沿雷达」于 2026-09-19 自动采集。标题与摘要版权归原作者所有，原链接见上。&lt;/p>
&lt;/blockquote></description></item><item><title>KoNeoBench: A Curated Evaluation Dataset for LLM Understanding of Korean Neologisms</title><link>https://pangyd.com/post/radar-89/</link><pubDate>Thu, 17 Sep 2026 16:58:49 +0800</pubDate><guid>https://pangyd.com/post/radar-89/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>原文&lt;/strong>：&lt;a href="https://arxiv.org/abs/2609.19916v1">KoNeoBench: A Curated Evaluation Dataset for LLM Understanding of Korean Neologisms&lt;/a>&lt;/p>
&lt;p>&lt;strong>作者&lt;/strong>：Soha Lee, Soojin Lee, Heesung Yang, Hyunju Song, Hyunji Lee, Jinsan An, Jeongwan Shin, Jin Hyun Park, Jun Lee, Hyeyoung Park, Kilim Nam&lt;/p>
&lt;p>&lt;strong>来源&lt;/strong>：arXiv cs.CL（自然语言）&lt;/p>
&lt;/blockquote>
&lt;h2 id="正文">正文&lt;/h2>
&lt;p>Computer Science &amp;gt; Computation and Language&lt;/p>
&lt;p>arXiv:2609.19916v1 (cs)&lt;/p>
&lt;p>[Submitted on 17 Sep 2026]&lt;/p>
&lt;p>Title:KoNeoBench: A Curated Evaluation Dataset for LLM Understanding of Korean Neologisms&lt;/p>
&lt;p>Authors:Soha Lee, Soojin Lee, Heesung Yang, Hyunju Song, Hyunji Lee, Jinsan An, Jeongwan Shin, Jin Hyun Park, Jun Lee, Hyeyoung Park, Kilim Nam&lt;/p></description></item><item><title>DualSQL: Text-to-SQL with Multi-Agent Reinforcement Learning</title><link>https://pangyd.com/post/radar-199/</link><pubDate>Wed, 16 Sep 2026 13:16:37 +0800</pubDate><guid>https://pangyd.com/post/radar-199/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>原文&lt;/strong>：&lt;a href="https://arxiv.org/abs/2609.18135v1">DualSQL: Text-to-SQL with Multi-Agent Reinforcement Learning&lt;/a>&lt;/p>
&lt;p>&lt;strong>作者&lt;/strong>：Shijie Chen, Yu Gan, Yeounoh Chung, Jiani Zhang, Quannan Li, Sravan Babu Bodapati, Cody J. Greer, Yu Su, Fatma Ozcan&lt;/p>
&lt;p>&lt;strong>来源&lt;/strong>：arXiv cs.DB（数据库）&lt;/p>
&lt;/blockquote>
&lt;h2 id="正文">正文&lt;/h2>
&lt;p>Computer Science &amp;gt; Computation and Language&lt;/p>
&lt;p>arXiv:2609.18135v1 (cs)&lt;/p>
&lt;p>[Submitted on 16 Sep 2026]&lt;/p>
&lt;p>Title:DualSQL: Text-to-SQL with Multi-Agent Reinforcement Learning&lt;/p>
&lt;p>Authors:Shijie Chen, Yu Gan, Yeounoh Chung, Jiani Zhang, Quannan Li, Sravan Babu Bodapati, Cody J. Greer, Yu Su, Fatma Ozcan&lt;/p>
&lt;p>View a PDF of the paper titled DualSQL: Text-to-SQL with Multi-Agent Reinforcement Learning, by Shijie Chen and 8 other authors&lt;/p></description></item><item><title>The Stochastic Deputy: Structural Tenant Isolation for Tool-Using LLM Agents</title><link>https://pangyd.com/post/radar-210/</link><pubDate>Mon, 14 Sep 2026 04:40:11 +0800</pubDate><guid>https://pangyd.com/post/radar-210/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>原文&lt;/strong>：&lt;a href="https://arxiv.org/abs/2609.14780v1">The Stochastic Deputy: Structural Tenant Isolation for Tool-Using LLM Agents&lt;/a>&lt;/p>
&lt;p>&lt;strong>作者&lt;/strong>：Mirza Samad Ahmed Baig, Syeda Anshrah Gillani, Asher Ali, Muhammad Hamzah Siddiqui&lt;/p>
&lt;p>&lt;strong>来源&lt;/strong>：arXiv cs.DB（数据库）&lt;/p>
&lt;/blockquote>
&lt;h2 id="正文">正文&lt;/h2>
&lt;p>Computer Science &amp;gt; Cryptography and Security&lt;/p>
&lt;p>arXiv:2609.14780v1 (cs)&lt;/p>
&lt;p>[Submitted on 13 Sep 2026]&lt;/p>
&lt;p>Title:The Stochastic Deputy: Structural Tenant Isolation for Tool-Using LLM Agents&lt;/p>
&lt;p>Authors:Mirza Samad Ahmed Baig, Syeda Anshrah Gillani, Asher Ali, Muhammad Hamzah Siddiqui&lt;/p>
&lt;p>View a PDF of the paper titled The Stochastic Deputy: Structural Tenant Isolation for Tool-Using LLM Agents, by Mirza Samad Ahmed Baig and 3 other authors&lt;/p></description></item><item><title>Natural Language Knowledge Graph Query Execution: Leveraging Controlled Semantics in the LLM Context Window</title><link>https://pangyd.com/post/radar-211/</link><pubDate>Mon, 14 Sep 2026 00:36:40 +0800</pubDate><guid>https://pangyd.com/post/radar-211/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>原文&lt;/strong>：&lt;a href="https://arxiv.org/abs/2609.14652v1">Natural Language Knowledge Graph Query Execution: Leveraging Controlled Semantics in the LLM Context Window&lt;/a>&lt;/p>
&lt;p>&lt;strong>作者&lt;/strong>：Blake G. Fitch&lt;/p>
&lt;p>&lt;strong>来源&lt;/strong>：arXiv cs.DB（数据库）&lt;/p>
&lt;/blockquote>
&lt;h2 id="正文">正文&lt;/h2>
&lt;p>Computer Science &amp;gt; Databases&lt;/p>
&lt;p>arXiv:2609.14652v1 (cs)&lt;/p>
&lt;p>[Submitted on 13 Sep 2026]&lt;/p>
&lt;p>Title:Natural Language Knowledge Graph Query Execution: Leveraging Controlled Semantics in the LLM Context Window&lt;/p>
&lt;p>Authors:Blake G. Fitch&lt;/p>
&lt;p>View a PDF of the paper titled Natural Language Knowledge Graph Query Execution: Leveraging Controlled Semantics in the LLM Context Window, by Blake G. Fitch&lt;/p></description></item><item><title>ES 增删改查操作</title><link>https://pangyd.com/post/233-es/</link><pubDate>Thu, 05 Mar 2020 22:41:24 +0800</pubDate><guid>https://pangyd.com/post/233-es/</guid><description>&lt;p>&lt;br>&lt;/p>&lt;h2 md-src-pos="12..17">创建&lt;/h2>&lt;h3 md-src-pos="18..29">自定义ID增加&lt;/h3>&lt;pre>&lt;code md-src-pos="30..92">PUT /{index}/{type}/{id}
{
 "field": "value",
 ...
}
&lt;/code>&lt;/pre>&lt;h3 md-src-pos="93..103">自动增加ID&lt;/h3>&lt;blockquote md-src-pos="104..114">&lt;p md-src-pos="106..114">使用post方式&lt;/p>&lt;/blockquote>&lt;pre>&lt;code md-src-pos="115..244">POST /website/blog/
{
 "title": "My second blog entry",
 "text": "Still trying this out...",
 "date": "2014/01/01"
}
&lt;/code>&lt;/pre>&lt;h2 md-src-pos="245..250">更新&lt;/h2>&lt;pre>&lt;code md-src-pos="251..380">PUT /website/blog/123
{
 "title": "My first blog entry",
 "text": "Just trying this out...",
 "date": "2014/01/01"
}
&lt;/code>&lt;/pre>&lt;blockquote md-src-pos="381..467">&lt;p md-src-pos="383..467">我们能看到 Elasticsearch 已经增加了 _version 字段值，created 标志设置成 false ，是因为相同的索引、类型和 ID 的文档已经存在。&lt;/p>&lt;/blockquote>&lt;h2 md-src-pos="468..473">删除&lt;/h2>&lt;pre>&lt;code md-src-pos="474..506">DELETE /website/blog/123
&lt;/code>&lt;/pre>&lt;blockquote md-src-pos="507..554">&lt;p md-src-pos="508..554">如果找到该文档，Elasticsearch 将要返回一个 200 ok 的 HTTP 响应码&lt;/p></description></item><item><title>Collections 内建集合模块</title><link>https://pangyd.com/post/231-collections/</link><pubDate>Fri, 28 Feb 2020 17:01:13 +0800</pubDate><guid>https://pangyd.com/post/231-collections/</guid><description>&lt;p>&lt;/p>&lt;p>&lt;span lang="EN-US">Collections&amp;nbsp;&lt;/span>集合类&lt;span lang="EN-US">&lt;/span>&lt;/p>&lt;h3>&lt;span lang="EN-US">namedtuple&lt;/span>&lt;/h3>&lt;p>我们知道&lt;code>&lt;span lang="EN-US">tuple&lt;/span>&lt;/code>可以表示不变集合，例如，一个点的二维坐标就可以表示成：&lt;span lang="EN-US">&lt;/span>&lt;/p>&lt;pre>&lt;span class="prompt">&lt;span lang="EN-US">&amp;gt;&amp;gt;&amp;gt; &lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">p = (&lt;/span>&lt;/code>&lt;span class="number">&lt;span lang="EN-US">1&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">, &lt;/span>&lt;/code>&lt;span class="number">&lt;span lang="EN-US">2&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">)&lt;/span>&lt;/code>&lt;/pre>&lt;p>但是，看到&lt;code>&lt;span lang="EN-US">(1, 2)&lt;/span>&lt;/code>，很难看出这个&lt;code>&lt;span lang="EN-US">tuple&lt;/span>&lt;/code>是用来表示一个坐标的。&lt;span lang="EN-US">&lt;/span>&lt;/p>&lt;p>定义一个&lt;span lang="EN-US">class&lt;/span>又小题大做了，这时，&lt;code>&lt;span lang="EN-US">namedtuple&lt;/span>&lt;/code>就派上了用场：&lt;span lang="EN-US">&lt;/span>&lt;/p>&lt;pre>&lt;span class="prompt">&lt;span lang="EN-US">&amp;gt;&amp;gt;&amp;gt; &lt;/span>&lt;/span>&lt;span class="keyword">&lt;span lang="EN-US">from&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US"> collections &lt;/span>&lt;/code>&lt;span class="keyword">&lt;span lang="EN-US">import&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US"> namedtuple&lt;/span>&lt;/code>&lt;/pre>&lt;pre>&lt;span class="prompt">&lt;span lang="EN-US">&amp;gt;&amp;gt;&amp;gt; &lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">Point = namedtuple(&lt;/span>&lt;/code>&lt;span class="string">&lt;span lang="EN-US">'Point'&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">, [&lt;/span>&lt;/code>&lt;span class="string">&lt;span lang="EN-US">'x'&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">, &lt;/span>&lt;/code>&lt;span class="string">&lt;span lang="EN-US">'y'&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">])&lt;/span>&lt;/code>&lt;/pre>&lt;pre>&lt;span class="prompt">&lt;span lang="EN-US">&amp;gt;&amp;gt;&amp;gt; &lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">p = Point(&lt;/span>&lt;/code>&lt;span class="number">&lt;span lang="EN-US">1&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">, &lt;/span>&lt;/code>&lt;span class="number">&lt;span lang="EN-US">2&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">)&lt;/span>&lt;/code>&lt;/pre>&lt;pre>&lt;span class="prompt">&lt;span lang="EN-US">&amp;gt;&amp;gt;&amp;gt; &lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">p.x&lt;/span>&lt;/code>&lt;/pre>&lt;pre>&lt;span class="number">&lt;span lang="EN-US">1&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">&lt;/span>&lt;/code>&lt;/pre>&lt;pre>&lt;span class="prompt">&lt;span lang="EN-US">&amp;gt;&amp;gt;&amp;gt; &lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">p.y&lt;/span>&lt;/code>&lt;/pre>&lt;pre>&lt;span class="number">&lt;span lang="EN-US">2&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">&lt;/span>&lt;/code>&lt;/pre>&lt;p>&lt;code>&lt;span lang="EN-US">namedtuple&lt;/span>&lt;/code>是一个函数，它用来创建一个自定义的&lt;code>&lt;span lang="EN-US">tuple&lt;/span>&lt;/code>对象，并且规定了&lt;code>&lt;span lang="EN-US">tuple&lt;/span>&lt;/code>元素的个数，并可以用属性而不是索引来引用&lt;code>&lt;span lang="EN-US">tuple&lt;/span>&lt;/code>的某个元素。&lt;span lang="EN-US">&lt;/span>&lt;/p>&lt;p>这样一来，我们用&lt;code>&lt;span lang="EN-US">namedtuple&lt;/span>&lt;/code>可以很方便地定义一种数据类型，它具备&lt;span lang="EN-US">tuple&lt;/span>的不变性，又可以根据属性来引用，使用十分方便。&lt;span lang="EN-US">&lt;/span>&lt;/p>&lt;p>可以验证创建的&lt;code>&lt;span lang="EN-US">Point&lt;/span>&lt;/code>对象是&lt;code>&lt;span lang="EN-US">tuple&lt;/span>&lt;/code>的一种子类：&lt;span lang="EN-US">&lt;/span>&lt;/p>&lt;pre>&lt;span class="prompt">&lt;span lang="EN-US">&amp;gt;&amp;gt;&amp;gt; &lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">isinstance(p, Point)&lt;/span>&lt;/code>&lt;/pre>&lt;pre>&lt;span class="builtin">&lt;span lang="EN-US">True&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">&lt;/span>&lt;/code>&lt;/pre>&lt;pre>&lt;span class="prompt">&lt;span lang="EN-US">&amp;gt;&amp;gt;&amp;gt; &lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">isinstance(p, tuple)&lt;/span>&lt;/code>&lt;/pre>&lt;pre>&lt;span class="builtin">&lt;span lang="EN-US">True&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">&lt;/span>&lt;/code>&lt;/pre>&lt;p>类似的，如果要用坐标和半径表示一个圆，也可以用&lt;code>&lt;span lang="EN-US">namedtuple&lt;/span>&lt;/code>定义：&lt;span lang="EN-US">&lt;/span>&lt;/p>&lt;pre>&lt;span class="comment">&lt;span lang="EN-US"># namedtuple('&lt;/span>名称&lt;span lang="EN-US">', [&lt;/span>属性&lt;span lang="EN-US">list]):&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">&lt;/span>&lt;/code>&lt;/pre>&lt;pre>&lt;span class="constant">&lt;span lang="EN-US">Circle&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US"> = namedtuple(&lt;/span>&lt;/code>&lt;span class="string">&lt;span lang="EN-US">'Circle'&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">, [&lt;/span>&lt;/code>&lt;span class="string">&lt;span lang="EN-US">'x'&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">, &lt;/span>&lt;/code>&lt;span class="string">&lt;span lang="EN-US">'y'&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">, &lt;/span>&lt;/code>&lt;span class="string">&lt;span lang="EN-US">'r'&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">])&lt;/span>&lt;/code>&lt;/pre>&lt;p>&lt;span lang="EN-US">&amp;nbsp;&lt;/span>&lt;/p>&lt;p>&lt;b>&lt;span lang="EN-US">Deque&lt;/span>&lt;/b>&lt;span lang="EN-US">&amp;nbsp;&amp;nbsp;&lt;/span>双向队列&lt;span lang="EN-US">&lt;/span>&lt;/p>&lt;p>使用&lt;code>&lt;span lang="EN-US">list&lt;/span>&lt;/code>存储数据时，按索引访问元素很快，但是插入和删除元素就很慢了，因为&lt;code>&lt;span lang="EN-US">list&lt;/span>&lt;/code>是线性存储，数据量大的时候，插入和删除效率很低。&lt;span lang="EN-US">&lt;/span>&lt;/p>&lt;p>&lt;span lang="EN-US">deque&lt;/span>是为了高效实现插入和删除操作的双向列表，适合用于队列和栈：&lt;span lang="EN-US">&lt;/span>&lt;/p>&lt;p>&lt;span lang="EN-US">list&lt;/span>是线性存储，数据量大的时候，效率慢&lt;span lang="EN-US">&lt;/span>&lt;/p>&lt;p>&lt;code>&lt;span lang="EN-US">deque&lt;/span>&lt;/code>除了实现&lt;span lang="EN-US">list&lt;/span>的&lt;code>&lt;span lang="EN-US">append()&lt;/span>&lt;/code>和&lt;code>&lt;span lang="EN-US">pop()&lt;/span>&lt;/code>外，还支持&lt;code>&lt;span lang="EN-US">appendleft()&lt;/span>&lt;/code>和&lt;code>&lt;span lang="EN-US">popleft()&lt;/span>&lt;/code>，这样就可以非常高效地往头部添加或删除元素。&lt;span lang="EN-US">&lt;/span>&lt;/p>&lt;p align="left">&lt;b>&lt;span lang="EN-US">defaultdict&lt;/span>&lt;/b>&lt;/p>&lt;p align="left">使用&lt;span lang="EN-US">dict&lt;/span>时，如果引用的&lt;span lang="EN-US">Key&lt;/span>不存在，就会抛出&lt;span lang="EN-US">KeyError&lt;/span>。如果希望&lt;span lang="EN-US">key&lt;/span>不存在时，返回一个默认值，就可以用&lt;span lang="EN-US">defaultdict&lt;/span>：&lt;span lang="EN-US">&lt;/span>&lt;/p>&lt;p align="left">&lt;span lang="EN-US">&amp;gt;&amp;gt;&amp;gt; from collections import defaultdict&lt;/span>&lt;/p>&lt;p align="left">&lt;span lang="EN-US">&amp;gt;&amp;gt;&amp;gt; dd = defaultdict(lambda: 'N/A')&lt;/span>&lt;/p>&lt;p align="left">&lt;span lang="EN-US">&amp;gt;&amp;gt;&amp;gt; dd['key1'] = 'abc'&lt;/span>&lt;/p>&lt;p align="left">&lt;span lang="EN-US">&amp;gt;&amp;gt;&amp;gt; dd['key1'] # key1&lt;/span>存在&lt;span lang="EN-US">&lt;/span>&lt;/p>&lt;p align="left">&lt;span lang="EN-US">'abc'&lt;/span>&lt;/p>&lt;p align="left">&lt;span lang="EN-US">&amp;gt;&amp;gt;&amp;gt; dd['key2'] # key2&lt;/span>不存在，返回默认值&lt;span lang="EN-US">&lt;/span>&lt;/p></description></item><item><title>济宁职业技术学院庞玉栋，王永强，刘明帅同学在“大数据技术与应用”国赛中获一等奖</title><link>https://pangyd.com/post/232/</link><pubDate>Wed, 04 Dec 2019 22:25:52 +0800</pubDate><guid>https://pangyd.com/post/232/</guid><description>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;img src="https://pangyd.com/uploads/2020/03/3395e6d4f16c86b9.jpg" alt="图片1.jpg">&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;img src="https://pangyd.com/uploads/2020/03/a5844cf157db4b39.jpg" alt="X[_[%360Q38$(9J{1F7FBQG.jpg">&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span>2019&lt;/span>&lt;span>年（高职组）&lt;/span>&lt;span>“新华三”杯大数据技术与应用&lt;/span>&lt;span>&lt;span>国赛于&lt;/span>&lt;span>6&lt;/span>&lt;span>月&lt;/span>&lt;span>13&lt;/span>&lt;span>日在贵州轻工职业技术学院举行，全国&lt;/span>&lt;span>28&lt;/span>&lt;span>个省市&lt;/span>&lt;span>98&lt;/span>&lt;span>所职业院校队参加比赛，决出金牌&lt;/span>&lt;span>10&lt;/span>&lt;span>个。&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>我院参赛选手庞玉栋、&lt;a target="_blank" href="https://lmshuai.com/?tdsourcetag=s_pctim_aiomsg">刘明帅&lt;/a>、王永强经过激烈地角逐获大赛一等奖，王秀芳、范建淑获优秀指导教师。至此，我院参赛选手在2019年国赛中全部获得一等奖。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>比赛包括大数据平台搭建、大数据采集、大数据清洗、大数据分析、大数据可视化等技能竞赛五个环节，竞赛时间为&lt;/span>&lt;span>240&lt;/span>&lt;span>分钟。其中大数据应用基本技能竞赛环节以团队竞赛方式进行，岗位职业素养考核穿插在大数据应用基本技能竞赛环节中进行。&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>比赛中充分展现了我省学生扎实的专业基础、实践能力与创新能力，以及职业素养和团队合作精神。&lt;/span>&lt;/span>&lt;/p></description></item><item><title>Matplotlib 雷达图详解</title><link>https://pangyd.com/post/230-matplotlib/</link><pubDate>Sun, 01 Dec 2019 10:07:16 +0800</pubDate><guid>https://pangyd.com/post/230-matplotlib/</guid><description>&lt;p>创建figure对象&amp;nbsp; 设置画布大小&amp;nbsp; 背景颜色&lt;/p>&lt;p>fig = plt.figure(figsize=(10,8))&lt;/p>&lt;p>创建图形图像&amp;nbsp; 设置以极坐标的方式显示&lt;/p>&lt;p>ax = fig.add_subplot(111,polar=True)&lt;/p>&lt;p>生成角度列表&amp;nbsp;&amp;nbsp;&lt;/p>&lt;p>angle = np.linspace(0,2*np.pi,10，endpoint=False)&lt;/p>&lt;p>首尾相连&amp;nbsp; 形成闭合多边形&lt;/p>&lt;p>&lt;span>theta = np.append(theta, theta[&lt;/span>&lt;span class="hljs-number">0&lt;/span>&lt;span>])&lt;/span>&lt;/p>&lt;p>angle =&amp;nbsp; np.append(angle, angle[&lt;span class="hljs-number">0&lt;/span>])&lt;/p>&lt;p>作图 第一个 角度&amp;nbsp; 第二个 数据&amp;nbsp; 第三个 线条样式&amp;nbsp; 第四个 线段宽度&amp;nbsp; 第五个 标签文本&lt;/p>&lt;p>ax.plot(angle, centers], 'o-', linewidth=2, label=kinds[i])&lt;/p>&lt;p>填充颜色&amp;nbsp;&lt;/p>&lt;p>ax.fill(angle,centers,alpha=0.5)&lt;/p>&lt;p>设置显示标签&amp;nbsp; 设置标签所在位置 透明度&lt;/p>&lt;p>plt.legend(loc='best',bbox_to_anchor=(1.2,0.3,0.,0.8),framealpha=0.1,edgecolor='blue')&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>极坐标柱形图使用bar生成图形&lt;/p>&lt;p>theta = np.linspace(0,2*np.pi,20,endpoint=False)&lt;/p>&lt;p>radii = 10*np.random.rand(20)&lt;/p>&lt;p>width = np.pi/4*np.random.rand(20)&lt;/p>&lt;p>bar = ax.bar(theta,radii,widrth,bottom=0.0)&lt;/p>&lt;p>for a,b in zip(radii,bar):&lt;/p>&lt;p>&amp;nbsp; &amp;nbsp;b.set_facecolor=plt.cm.hot(a/10)&lt;/p>&lt;p>&amp;nbsp; &amp;nbsp;b.set_alpha=0.1&lt;/p></description></item><item><title>Java两种方法实现简单爬虫</title><link>https://pangyd.com/post/229-java/</link><pubDate>Thu, 28 Nov 2019 16:21:04 +0800</pubDate><guid>https://pangyd.com/post/229-java/</guid><description>&lt;p>第一种：利用HttpClient和Jsoup爬取网站数据&lt;/p>&lt;p>&lt;/p>&lt;pre lay-lang="Java" class="layui-code" skin="notepad">package com.company;
&lt;p>import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;&lt;/p>
&lt;p>public class Main {&lt;/p>
&lt;pre>&lt;code>public static void main (String[] args) throws Exception {
 // 创建默认的客户端实例
 CloseableHttpClient httpClient = HttpClients.createDefault();

 // 创建get请求实例
 HttpGet httpget = new HttpGet(&amp;quot;/&amp;quot;);

 System.out.println(&amp;quot;executing request &amp;quot; + httpget.getURI());
 String content = &amp;quot;&amp;quot;;

 try {
 // 客户端执行get请求返回响应
 CloseableHttpResponse response = httpClient.execute(httpget);

 // 服务器响应状态行
 System.out.println(response.getStatusLine().toString());

 Header[] heads = response.getAllHeaders();
 HttpEntity entity = response.getEntity();

 if (entity != null) {
 content += EntityUtils.toString(entity, &amp;quot;utf-8&amp;quot;);
 EntityUtils.consume(entity);// 关闭内容流
 }

 System.out.println(content);
 System.out.println(response.getHeaders(&amp;quot;Content-Type&amp;quot;));
 // 打印所有响应头

 for(Header h:heads){
 System.out.println(h.getName()+&amp;quot;:&amp;quot;+h.getValue());
 }
 } finally {
 httpClient.close();
 }
}
&lt;/code>&lt;/pre>
&lt;p>}&lt;/p></description></item><item><title>python操作mongo</title><link>https://pangyd.com/post/228-pythonmongo/</link><pubDate>Mon, 18 Nov 2019 18:01:43 +0800</pubDate><guid>https://pangyd.com/post/228-pythonmongo/</guid><description>&lt;p>&lt;span>连接mongodb&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;/p>&lt;pre lay-lang="JavaScript" class="layui-code" skin="notepad">#!/usr/bin/env python
# -*- coding:utf-8 -*-
&lt;p>from pymongo import MongoClient&lt;/p>
&lt;p>conn = MongoClient(&amp;lsquo;192.168.0.113&amp;rsquo;, 27017)
db = conn.mydb #连接mydb数据库，没有则自动创建
my_set = db.test_set　　#使用test_set集合，没有则自动创建&lt;/pre>&lt;p>&lt;span>插入数据（insert插入一个列表多条数据不用遍历，效率高， save需要遍历列表，一个个插入）&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;/p>&lt;pre lay-lang="JavaScript" class="layui-code" skin="notepad">my_set.insert({&amp;ldquo;name&amp;rdquo;:&amp;ldquo;zhangsan&amp;rdquo;,&amp;ldquo;age&amp;rdquo;:18})
#或
my_set.save({&amp;ldquo;name&amp;rdquo;:&amp;ldquo;zhangsan&amp;rdquo;,&amp;ldquo;age&amp;rdquo;:18})&lt;/pre>&lt;p>&lt;span>插入多条&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;/p>&lt;pre lay-lang="JavaScript" class="layui-code" skin="notepad">#添加多条数据到集合中
users=[{&amp;ldquo;name&amp;rdquo;:&amp;ldquo;zhangsan&amp;rdquo;,&amp;ldquo;age&amp;rdquo;:18},{&amp;ldquo;name&amp;rdquo;:&amp;ldquo;lisi&amp;rdquo;,&amp;ldquo;age&amp;rdquo;:20}]&lt;br>
my_set.insert(users)
#或
my_set.save(users) &lt;/pre>&lt;p>&lt;span>查询数据（查询不到则返回None）&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;/p>&lt;pre lay-lang="JavaScript" class="layui-code" skin="notepad">#查询全部
for i in my_set.find():
print(i)
#查询name=zhangsan的
for i in my_set.find({&amp;ldquo;name&amp;rdquo;:&amp;ldquo;zhangsan&amp;rdquo;}):
print(i)
print(my_set.find_one({&amp;ldquo;name&amp;rdquo;:&amp;ldquo;zhangsan&amp;rdquo;}))&lt;/pre>&lt;p>&lt;span>更新数据&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;/p>&lt;pre lay-lang="JavaScript" class="layui-code" skin="notepad">my_set.update(
&lt;query>, #查询条件
&lt;update>, #update的对象和一些更新的操作符
{
upsert: &lt;boolean>, #如果不存在update的记录，是否插入
multi: &lt;boolean>, #可选，mongodb 默认是false,只更新找到的第一条记录
writeConcern: &lt;document> #可选，抛出异常的级别。&lt;pre lay-lang="JavaScript" class="layui-code" skin="notepad">#删除name=lisi的全部记录
my_set.remove({&amp;rsquo;name&amp;rsquo;: &amp;lsquo;zhangsan&amp;rsquo;})&lt;/p></description></item><item><title>MongoDB笔记</title><link>https://pangyd.com/post/227-mongodb/</link><pubDate>Sat, 09 Nov 2019 11:19:19 +0800</pubDate><guid>https://pangyd.com/post/227-mongodb/</guid><description>&lt;p>&lt;b>&lt;i>MongoDB简介&lt;/i>&lt;/b>&lt;/p>&lt;p>&lt;b>MongoDB介绍&lt;/b>&lt;/p>&lt;pre data-anchor-id="8t84">&lt;code class="hljs less">&lt;span class="hljs-selector-tag">MongoDB&lt;/span>是面向文档的非关系型数据库，不是现在使用最普遍的关系型数据库，其放弃关系模型的原因就是为了获得更加方便的扩展、稳定容错等特性。面向文档的基本思路就是：将关系模型中的“行”的概念换成“文档（&lt;span class="hljs-selector-tag">document&lt;/span>）”模型。面向文档的模型可以将文档和数组内嵌到文档中。因此，实际中可以用一条数据表示非常复杂的结构。
&lt;span class="hljs-selector-tag">MongoDB&lt;/span>没有预定义模式：文档的键(key)和值(value)不再是固定的类型和大小，而且根据需求要添加或者删除字段变得更容易了。由于没有模式需要更改，通常不需要迁移大量数据。不必将所有数据都放到一个模子里面，应用层可以处理新增或丢失的键。这样开发者可以非常容易地变更数据模型。
实际应用中，随着数据量的增大，数据库都要进行扩展。扩展有纵向扩展和横向扩展。纵向扩展是使用计算能力更强的机器，也是最省力的方法，但是很容易达到物理极限，无论花多少钱也买不到最新的机器了。横向扩展就是通过分区将数据分散到更多的机器上。&lt;span class="hljs-selector-tag">MongoDB&lt;/span>的设计采用横向扩展。面向文档的数据模型使它很容易地在多台服务器之间进行数据分割。还可以自动处理跨集群的数据和负载，自动重新分配文档，以及将用户请求路由到正确的机器上。开发者根本不用考虑数据库层次的扩展问题，需要扩展数据库时，在集群中添加机器即可，&lt;span class="hljs-selector-tag">MongoDB&lt;/span>会自动处理后续的事情。
&lt;span class="hljs-selector-tag">MongoDB&lt;/span>有如上各种特性，但为了达到这些，他也放弃了关系型数据库的某些功能如表连接&lt;span class="hljs-selector-tag">join&lt;/span>和复杂的多行事务。&lt;/code>&lt;/pre>&lt;p>&lt;b>MongoDB的优势与劣势&lt;/b>&lt;/p>&lt;p>优势&lt;/p>&lt;p>快速！基于内存，将热数据存放在物理内存中（不仅仅只是索引和少部分数据），从而提高了整体速度和效率。&lt;/p>&lt;p>高扩展性！MongoDB的高可用和集群架构拥有十分高的扩展性。&lt;/p>&lt;p>自身的FailOver机制！在副本集中，当主库遇到问题，无法继续提供服务的时候，副本集将选举一个新的主库继续提供服务。&lt;/p>&lt;p>JSon格式的数据！MongoDB的Bson和JSon格式的数据十分适合文档格式的存储与查询。&lt;/p>&lt;div class="md-section-divider">&amp;nbsp;&lt;/div>&lt;p>劣势&lt;/p>&lt;p>应用经验少！由于NoSQL兴起时间短，应用经验相比关系型数据库较少。&lt;/p>&lt;p>由于以往用到的都是关系型数据库，可能会造成使用者一开始的不适应。&lt;/p>&lt;p>无事务机制！MongoDB本身没有自带事务机制，若需要在MongoDB中实现事务机制，需通过一个额外的表，从逻辑上自行实现事务。&lt;/p>&lt;p>&lt;b>MongoDB基础知识与CRUD&lt;/b>&lt;/p>&lt;p data-anchor-id="ejso">1.文档(document):相当于传统关系型数据库的“行”，但比传统行表示的信息更加复杂。例如：&lt;br>&lt;/p>&lt;p data-anchor-id="ejso">&lt;/p>&lt;pre lay-lang="Python" class="layui-code" skin="notepad">{"name":"jack","age":18,"sex":"male"}
&lt;/pre>&lt;br>&lt;p>&lt;/p>&lt;div class="md-section-divider">&lt;div class="cnblogs_Highlighter sh-gutter">&lt;/div>&lt;/div>&lt;p data-anchor-id="pz0y">2.集合(collection):这个在MongoDB中代表一组文档，类似于关系型数据库中的表。但在MongoDB中的表（就是集合）是没有模式的，你可以将完全不同的文档放入同一个集合中.但在实际使用中，为特定集合隐性规定一种模式。注：当集合里没有任何文档时集合其实也是不存在的。当第一个文档插入时，集合就会被创建。&amp;nbsp;&lt;br>3.数据库(database):在MongoDB中，一组集合可以组成一个数据库。一个MongoDB实例可以承载多个数据库。每个数据库都有独立的权限控制。在实际应用中，通常，一个应用的所有数据放置在一个数据库中。&amp;nbsp;&lt;br>4.数据类型：MongoDB中的文档类似于JSON。JSON是一种简单的数据交换格式，在数据类型方面，只支持：null，布尔，数字，字符串，数组和对象。这几种类型在某些实际应用中表现力还是不够，比如JSON本身不直接支持日期类型，对于数字，JSON本身也没法区分整数和浮点数，更不能区分32位数字和64位数字。为此，MongoDB再保留了JSON的各类特性外，又为其添加了一些数据类型。&amp;nbsp;&lt;br>1.null：用于表示空值或不存在的字段。Shell中这样表示：&lt;code>{"x"：null}&lt;/code>&amp;nbsp;&lt;br>2.布尔：有两个值，true和false。Shell中这样使用：&lt;code>{"x"：true}&lt;/code>&amp;nbsp;&lt;br>3.数字：Shell中数字均为64位浮点数，如在Shell中&lt;code>{"x"：3.14}&lt;/code>和&lt;code>{"x"：3}&lt;/code>这两个文档中的值均是64位的浮点数。&amp;nbsp;&lt;br>4.字符串：这个用的最广，Shell中这样表示：&lt;code>{"x"："hello world！"}&lt;/code>&amp;nbsp;&lt;br>5.日期：这个在数据存储时，存储的是从标准纪元开始的毫秒数，没有存储时区信息。&amp;nbsp;&lt;br>6.正则表达式：文档中可以包含正则表达式，采用JavaScript的正则表达式语法即可，Shell中这样表示：&lt;code>{"x"：/foobar/i}&lt;/code>。&lt;br>7.数组：数组是一组值，既可以表示为有序对象（列表，栈，队列等）也可以表示无序对象（集合），Shell中这样表示一个数组：&lt;code>{"things"：["pie"，3.14]}&lt;/code>。&amp;nbsp;&lt;br>8.内嵌文档：把一个文档整个作为另一个文档某一个键对应的值。&amp;nbsp;&lt;br>其他包括二进制数据，代码等。&lt;/p>&lt;h3 id="mongodb入门shell基本操作" data-anchor-id="60is">MongoDB入门(Shell基本操作)&lt;/h3>&lt;p>&lt;span>shell是一个功能完备的JavaScript解释器，可运行任意的JavaScript程序。这里不做示例。&amp;nbsp;&lt;/span>&lt;br>&lt;span>MongoDB的默认数据库为"db"，该数据库存储在data目录中。&amp;nbsp;&lt;/span>&lt;br>&lt;span>1.选择数据库&lt;/span>&lt;/p>&lt;p>&lt;/p>&lt;pre lay-lang="Python" class="layui-code" skin="notepad">#选择名test数据库
use tset&lt;/pre>&lt;p>&lt;span>如果忘记了数据库名称可以输入如下代码查询所有数据库名称："show dbs" 命令可以显示所有数据的列表&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;/p>&lt;pre lay-lang="JavaScript" class="layui-code" skin="notepad">show dbs&lt;/pre>&lt;p data-anchor-id="5h1c">查看数据库中的集合名：&lt;/p>&lt;div>&lt;pre lay-lang="JavaScript" class="layui-code" skin="notepad">show collections&lt;/pre>&lt;p>&lt;span>下表列出了 RDBMS 与 MongoDB 对应的术语：&amp;nbsp;&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;img src="https://pangyd.com/uploads/2019/05/ebe16666a468bd09.png" alt="2017-05-17_170031.png">&lt;br>&lt;/span>&lt;/p>&lt;h3 id="插入文档" data-anchor-id="3jei">插入文档&lt;/h3>&lt;/div>&lt;p>&lt;/p>&lt;p data-anchor-id="hbt8">insert函数可将一个文档插入到集合中去。以一个博客举例。先创建一个叫post的变量(JavaScript对象)有三个键和对应的属性。插入代码：&lt;/p>&lt;p data-anchor-id="hbt8">&lt;/p>&lt;pre lay-lang="JavaScript" class="layui-code" skin="notepad">db.blog.insert(post)&lt;/pre>&lt;p>&lt;span>批量插入&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;/p>&lt;pre lay-lang="JavaScript" class="layui-code" skin="notepad">db.blog.insertMany([{"_id":0},{"_id":1},{"_id":2}])&lt;/pre>&lt;h3 id="查询文档" data-anchor-id="6u2w">查询文档&lt;/h3>&lt;p>&lt;/p>&lt;p data-anchor-id="p2pt">查询代码如下：&lt;/p>&lt;p data-anchor-id="p2pt">&lt;/p>&lt;pre lay-lang="JavaScript" class="layui-code" skin="notepad">db.blog.find()&lt;/pre>&lt;p>&lt;span>多出来的"_id"就是MongoDB自动创建的默认为ObjectID类型的对象。在一个集合里，每个文档都由唯一的"_id",确保集合中的每个文档都能被唯一标识，它采用12字节的存储空间，由24个16进制数字组成。&lt;/span>&lt;/p>&lt;p>&lt;span>如果插入文档时没有"_id"键，系统会为我们自动创建一个。&amp;nbsp;&lt;/span>&lt;br>&lt;/p>&lt;p>&lt;span>若只想查看一个文档，可以用findOne：&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;/p></description></item><item><title>Matplotlib模块整理</title><link>https://pangyd.com/post/226-matplotlib/</link><pubDate>Fri, 08 Nov 2019 11:53:24 +0800</pubDate><guid>https://pangyd.com/post/226-matplotlib/</guid><description>&lt;img src="https://pangyd.com/uploads/2019/05/c209f3e0a8b3557e.png" alt="FireShot Capture 004 - Untitled - localhost_gaitubao_1304x21192.png"></description></item><item><title>猎聘网站爬虫（代理池+邮件提醒+写入flume服务端）</title><link>https://pangyd.com/post/225-flume/</link><pubDate>Thu, 31 Oct 2019 11:44:38 +0800</pubDate><guid>https://pangyd.com/post/225-flume/</guid><description>&lt;pre lay-lang="Python" class="layui-code" skin="notepad"># coding=utf-8
import requests
import re
import time
import json
from demo2 import soct
import pymysql
import random
import smtplib
import email.mime.multipart
import email.mime.text
&lt;p>import socket&lt;/p>class Spider():

 def __init__(self):
 self.ls = []
 self.count = 0
 self.USER_AGENTS = [
 "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; AcooBrowser; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
 "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Acoo Browser; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506)",
 "Mozilla/4.0 (compatible; MSIE 7.0; AOL 9.5; AOLBuild 4337.35; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
 "Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US)",
 "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)",
 "Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.0.3705; .NET CLR 1.1.4322)",
 "Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.04506.30)",
 "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/523.15 (KHTML, like Gecko, Safari/419.3) Arora/0.3 (Change: 287 c9dfb30)",
 "Mozilla/5.0 (X11; U; Linux; en-US) AppleWebKit/527+ (KHTML, like Gecko, Safari/419.3) Arora/0.6",
 "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.2pre) Gecko/20070215 K-Ninja/2.1.1",
 "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9) Gecko/20080705 Firefox/3.0 Kapiko/3.0",
 "Mozilla/5.0 (X11; Linux i686; U;) Gecko/20070322 Kazehakase/0.4.5",
 "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.8) Gecko Fedora/1.9.0.8-1.fc10 Kazehakase/0.5.6",
 "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11",
 "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.20 (KHTML, like Gecko) Chrome/19.0.1036.7 Safari/535.20",
 "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; fr) Presto/2.9.168 Version/11.52",
 ]

 def emial(self):
 try:
 subject = 'python执行日志'
 content = "可用{}个代理ip，所有url已经爬取完毕".format(len(self.ls))
 msg = email.mime.multipart.MIMEMultipart()
&lt;p> msg['from'] = '******@qq.com'&lt;/p></description></item><item><title>Matplotlib可视化库的简单使用</title><link>https://pangyd.com/post/224-matplotlib/</link><pubDate>Thu, 24 Oct 2019 15:24:00 +0800</pubDate><guid>https://pangyd.com/post/224-matplotlib/</guid><description>&lt;p>常见的图表类型&lt;/p>&lt;p>直方图：适用比较数据之间的多少；折线图：反映一组数据的变化趋势；条形图：显示各个项目之间的比较情况&amp;nbsp; 和直方图有类似的作用；饼图；散点图：显示若干数据系列中各数值之间的关系 类似X，Y轴，判读两变量之间是否存在某种关联；箱型图：识别异常值方面有一定的优越性&lt;/p>&lt;p>直方图与条形图的具体区别如下：&lt;/p>&lt;p>首先，条形图用条形的长度表示各类别频率快的多少&amp;nbsp; 其宽度是固定的&amp;nbsp; 直方图是用面积表示各组频数的多少&amp;nbsp; 矩形的高度表示每一组的频数和频率，，宽度则表示各组的组距，因此其高度与宽度均有意义。其次，由于分组数据具有连续性 所以直方图的各矩形通常都是连续排列的&amp;nbsp; 而条形图则是分开排列的&amp;nbsp; 最后 条形图主要用于展示分类数据&amp;nbsp; 而直方图则主要用于展示数据型数据。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>1通过subplot创建单个子图&lt;/p>&lt;p>&lt;/p>&lt;pre lay-lang="Python" class="layui-code" skin="notepad">#分成2*2的矩阵区域 
plt.subplot(221)
plt.plot(nums,nums)
plt.subplot(222)
plt.plot(nums,-nums)
plt.subplot(212)
plt.plot(nums,nums**2)
plt.show()&lt;/pre>&lt;p>2通过subplots创建多个子图&lt;/p>&lt;p>&lt;/p>&lt;pre lay-lang="Python" class="layui-code" skin="notepad">#生成包含1～100之间所有整数数组
nums = np.arange(1,101)
#分成2*2的矩阵区域 返回子图数组axes
fig,axes = plt.subplots(2,2)
axes[0,0].plot(nums,nums)
&lt;p>plt.show()&lt;img src="https://pangyd.com/uploads/2019/10/ef0d7566a3745997.png">&lt;/p>&lt;/pre>&lt;p>3通过add_subplot添加和选中子图&lt;/p>&lt;p>&lt;/p>&lt;pre lay-lang="Python" class="layui-code" skin="notepad">fig = plt.figure()
#添加子图
fig.add_subplot(2,2,1)
fig.add_subplot(2,2,2)
fig.add_subplot(2,2,4)
fig.add_subplot(2,2,3)
#在子图上作图
random_arr = np.random.randn(100)
#默认是在最后一次使用subplot的位置上作图 即编号为3的位置
plt.plot(random_arr)
&lt;p>plt.show()&lt;img src="https://pangyd.com/uploads/2019/10/d818a87fb38a28b7.png">&lt;/p>&lt;/pre>&lt;p>4添加各类标签&lt;/p>&lt;p>图表添加标签和图例的常用函数&lt;/p>&lt;p>title():设置当前轴的标题&lt;/p>&lt;p>xlabel():设置当前图形X轴的标签名称&lt;/p>&lt;p>ylabel():设置当前图形Y轴的标签名称&lt;/p>&lt;p>xticks():指定X轴刻度的数目与取值&lt;/p>&lt;p>yticks():指定Y轴刻度的数目与取值&lt;/p>&lt;p>xlim():设置或获取当前图形X轴的范围&lt;/p>&lt;p>ylim():设置或获取的当前图形Y轴的范围&lt;/p>&lt;p>legend():在轴上放置一个图例&lt;/p>&lt;p>&lt;/p>&lt;pre lay-lang="Python" class="layui-code" skin="notepad">import numpy as np
data = np.arange(0,1.1,0.01)
plt.title('Title')
plt.xlabel('x')
plt.ylabel('y')
#设置x和y轴的刻度
plt.xticks([0,0.5,1])
plt.yticks([0,0.5,1.0])
plt.plot(data,data**2,lineStyle='-.')
plt.plot(data,data**3)
plt.legend(['y=x^2','y=x^3'])
&lt;p>plt.show(&lt;img src="https://pangyd.com/uploads/2019/10/3e3685c1adefb804.png">&lt;/p></description></item><item><title>爬取斗图网表情包</title><link>https://pangyd.com/post/223/</link><pubDate>Sat, 12 Oct 2019 20:59:15 +0800</pubDate><guid>https://pangyd.com/post/223/</guid><description>&lt;pre lay-lang="Python" class="layui-code" skin="notepad">#需要安装的库：requests lxml
import requests
import re
from lxml.html import etree
import os
import time
#伪装头
headers = {
 'referer': 'https://www.doutula.com/article/list/?page=3',
 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3783.0 Safari/537.36'
}
#先爬取100个页面
for s in range(1,100):
 url = 'https://www.doutula.com/article/list/?page={}'.format(s)
 try:
 res = requests.get(url,headers=headers)
 except Exception as e:
 continue
 csc = etree.HTML(res.text)
 ds = {}
 #解析出来每个页面的表情包标题和网址添加到ds字典
 for i in csc.xpath('//*[@id="home"]/div/div[2]//a'):
 if i.xpath('@href')[0][0:4]=='http':
 ds[i.xpath('div[1]/text()')[0]] = i.xpath('@href')[0]
 #循环字典，并在指定目录创建文件夹，存放表情包
 for a,b in ds.items():
 file_path = '/Users/pyd/Documents/BigData/gs2/doutu/{}'.format(a)
 if not os.path.exists(file_path):
 os.mkdir(file_path)
 else:
 continue
 try:
 cbv = requests.get(b,headers=headers,timeout=5)
 except Exception as e:
 continue
&lt;p>&lt;/p></description></item><item><title>SQLAlchemy_定义(一对一/一对多/多对多)关系</title><link>https://pangyd.com/post/222-sqlalchemy/</link><pubDate>Tue, 08 Oct 2019 10:32:05 +0800</pubDate><guid>https://pangyd.com/post/222-sqlalchemy/</guid><description>&lt;p>Basic Relationship Patterns&lt;/p>&lt;p>基本关系模式&lt;/p>&lt;p>The imports used for each of the following sections is as follows:&lt;/p>&lt;p>下列的 import 语句，应用到接下来所有的代章节中：&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>from sqlalchemy import Table, Column, Integer, ForeignKey&lt;/p>&lt;p>from sqlalchemy.orm import relationship&lt;/p>&lt;p>from sqlalchemy.ext.declarative import declarative_base&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>Base = declarative_base()&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>One To Many&lt;/p>&lt;p>A one to many relationship places a foreign key on the child table referencing the parent.&lt;/p>&lt;p>表示一对多的关系时，在子表类中通过 foreign key (外键)引用父表类。&lt;/p>&lt;p>relationship() is then specified on the parent, as referencing a collection of items represented by the child:&lt;/p></description></item><item><title>flask-sqlalchemy 使用详解</title><link>https://pangyd.com/post/221-flask-sqlalchemy/</link><pubDate>Thu, 03 Oct 2019 19:47:58 +0800</pubDate><guid>https://pangyd.com/post/221-flask-sqlalchemy/</guid><description>&lt;h2 id="一-安装">一. 安装&lt;/h2>&lt;pre class="has" name="code">&lt;code class="hljs sql">$ pip &lt;span class="hljs-keyword">install&lt;/span> flask-sqlalchemy
&lt;/code>&lt;/pre>&lt;h2 id="二-配置">&lt;a name="t1">&lt;/a>二. 配置&lt;/h2>&lt;p>配置选项列表 :&lt;/p>&lt;div class="table-box">&lt;table class="layui-table">&lt;thead>&lt;tr>&lt;th style="text-align: left">选项&lt;/th>&lt;th style="text-align: left">说明&lt;/th>&lt;/tr>&lt;/thead>&lt;tbody>&lt;tr>&lt;td>SQLALCHEMY_DATABASE_URI&lt;/td>&lt;td>用于连接的数据库 URI 。例如:sqlite:////tmp/test.db 或 mysql://username:password@server/db&lt;/td>&lt;/tr>&lt;tr>&lt;td>SQLALCHEMY_BINDS&lt;/td>&lt;td>一个映射 binds 到连接 URI 的字典。更多 binds 的信息见 用 Binds 操作多个数据库 。&lt;/td>&lt;/tr>&lt;tr>&lt;td>SQLALCHEMY_ECHO&lt;/td>&lt;td>如果设置为 Ture ， SQLAlchemy 会记录所有 发给 stderr 的语句，这对调试有用。&lt;/td>&lt;/tr>&lt;tr>&lt;td>SQLALCHEMY_RECORD_QUERIES&lt;/td>&lt;td>可以用于显式地禁用或启用查询记录。查询记录 在调试或测试模式自动启用。更多信息见 get_debug_queries() 。&lt;/td>&lt;/tr>&lt;/tbody>&lt;/table>&lt;/div>&lt;p>SQLALCHEMY_NATIVE_UNICODE | 可以用于显式禁用原生 unicode 支持。当使用 不合适的指定无编码的数据库默认值时，这对于 一些数据库适配器是必须的（比如 Ubuntu 上某些版本的 PostgreSQL ）。|&lt;br>| SQLALCHEMY_POOL_SIZE | 数据库连接池的大小。默认是引擎默认值（通常 是 5 ） |&lt;br>| SQLALCHEMY_POOL_TIMEOUT | 设定连接池的连接超时时间。默认是 10 。 |&lt;br>| SQLALCHEMY_POOL_RECYCLE | 多少秒后自动回收连接。这对 MySQL 是必要的， 它默认移除闲置多于 8 小时的连接。注意如果 使用了 MySQL ， Flask-SQLALchemy 自动设定这个值为 2 小时。|&lt;/p></description></item><item><title>Flume配置文件详解</title><link>https://pangyd.com/post/220-flume/</link><pubDate>Wed, 24 Jul 2019 09:26:42 +0800</pubDate><guid>https://pangyd.com/post/220-flume/</guid><description>&lt;p>一、source配置&lt;/p>&lt;p>1、netcat的source：bind指定IP，port指定port&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p># Describe/configure the source&lt;/p>&lt;p>a1.sources.r1.type = netcat&lt;/p>&lt;p>a1.sources.r1.bind = localhost&lt;/p>&lt;p>a1.sources.r1.port = 44444&lt;/p>&lt;p>2、读文件exec：commd中写命令，如果用tail的话记得用大写的F&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p># Describe/configure the source&lt;/p>&lt;p>a1.sources.r1.type = exec&lt;/p>&lt;p>a1.sources.r1.command = tail -F /opt/module/hive/logs/hive.log&lt;/p>&lt;p>a1.sources.r1.shell = /bin/bash -c&lt;/p>&lt;p>3、读取文件夹source：spooldir source ，tmp记得一定要忽略&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p># Describe/configure the source&lt;/p>&lt;p>a1.sources.r1.type = spooldir&lt;/p>&lt;p># 指定文件夹&lt;/p>&lt;p>a1.sources.r1.spoolDir = /opt/module/flume/upload&lt;/p>&lt;p>#指定文件上传后的后缀&lt;/p>&lt;p>a1.sources.r1.fileSuffix = .COMPLETED&lt;/p>&lt;p>a1.sources.r1.fileHeader = true&lt;/p>&lt;p>#忽略所有以.tmp结尾的文件，不上传&lt;/p>&lt;p>a1.sources.r1.ignorePattern = ([^ ]*\.tmp)&lt;/p>&lt;p>4、最常用的source: arvo模式，bind指的是接收的主机，port不是随意的，是看sink给的端口&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p># Describe/configure the source&lt;/p>&lt;p>a1.sources.r1.type = avro&lt;/p></description></item><item><title>Flume采集数据时在HDFS上产生大量小文件的问题</title><link>https://pangyd.com/post/219-flumehdfs/</link><pubDate>Tue, 23 Jul 2019 09:15:03 +0800</pubDate><guid>https://pangyd.com/post/219-flumehdfs/</guid><description>&lt;p>在配置flume配置文件的时候，配置了滚动时间和最大字节数，但是在写入到hdfs的时候，其实是不按滚动时间去自动滚动的。&lt;/p>&lt;p>&lt;span>设置a1.sinks.k1.hdfs.minBlockReplicas=1。因为文件会因为所在块的复制而滚动文件。&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/p>&lt;p>&lt;span>或者&lt;/span>&lt;/p>&lt;p>去掉round时间系列参数，并将rollSize和rollCount置0，表示不根据临时文件大小和event数量来滚动文件（滚动文件即指将HDFS上生成的以.tmp结尾的临时文件转换为实际存储文件）。当然，也可以调大rollSize参数（如调至100000000,表示100MB滚动文件，单位是bytes）。&lt;/p></description></item><item><title>flask传递列表等到jinja2模版的时候出现'；</title><link>https://pangyd.com/post/218-flaskjinja2/</link><pubDate>Fri, 19 Jul 2019 09:09:34 +0800</pubDate><guid>https://pangyd.com/post/218-flaskjinja2/</guid><description>&lt;pre lay-lang="JavaScript" class="layui-code" skin="notepad">{% for i in connect.d %}
 "{{i[0]}}",
{% endfor %}#

#可以使用循环读取每一条数据&lt;/pre></description></item><item><title>智联招聘爬虫+email邮件发送</title><link>https://pangyd.com/post/217-email/</link><pubDate>Mon, 15 Jul 2019 09:04:11 +0800</pubDate><guid>https://pangyd.com/post/217-email/</guid><description>&lt;pre lay-lang="Python" class="layui-code" skin="notepad"># -*- coding: utf-8 -*-
import requests
import re
import time
import json
import pymysql
import random
import smtplib
import email.mime.multipart
import email.mime.text

class Spider():

 def __init__(self):
 self.ls = []
 self.count = 0
 self.USER_AGENTS = [
 "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; AcooBrowser; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
 "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Acoo Browser; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506)",
 "Mozilla/4.0 (compatible; MSIE 7.0; AOL 9.5; AOLBuild 4337.35; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
 "Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US)",
 "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)",
 "Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.0.3705; .NET CLR 1.1.4322)",
 "Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.04506.30)",
 "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/523.15 (KHTML, like Gecko, Safari/419.3) Arora/0.3 (Change: 287 c9dfb30)",
 "Mozilla/5.0 (X11; U; Linux; en-US) AppleWebKit/527+ (KHTML, like Gecko, Safari/419.3) Arora/0.6",
 "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.2pre) Gecko/20070215 K-Ninja/2.1.1",
 "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9) Gecko/20080705 Firefox/3.0 Kapiko/3.0",
 "Mozilla/5.0 (X11; Linux i686; U;) Gecko/20070322 Kazehakase/0.4.5",
 "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.8) Gecko Fedora/1.9.0.8-1.fc10 Kazehakase/0.5.6",
 "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11",
 "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.20 (KHTML, like Gecko) Chrome/19.0.1036.7 Safari/535.20",
 "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; fr) Presto/2.9.168 Version/11.52",
 ]

	#程序执行完毕后发送邮件函数
 def emial(self):
 try:
 subject = 'python执行日志'
 content = "可用{}个代理ip，所有url已经爬取完毕".format(len(self.ls))
 msg = email.mime.multipart.MIMEMultipart()
 msg['from'] = 'xxxxx@qq.com'
 msg['to'] = 'xxxx@qq.com'
 msg['subject'] = subject
 content = content
 txt = email.mime.text.MIMEText(content, 'plain', 'utf-8')
 msg.attach(txt)
 smtpHost = 'smtp.qq.com'
 smtpPort = '25'
 sslPort = '465'

 smtp = smtplib.SMTP_SSL(smtpHost, sslPort)
 smtp.ehlo()
 smtp.login('xxxxx@qq.com', 'xxxxx')
 smtp.sendmail('xxxx@qq.com', 'xxxxx@qq.com', str(msg))
 print("发送成功！")
 smtp.quit()
 except Exception as e:
 print(e)

	#从数据库中查询代理函数
 def sql(self):
 try:
 db = pymysql.connect(host="xxxxxxxxxx", user="xxxxxx", password="xxxxxx", db="xxxxx", port=3306,
 charset="utf8")
 cur = db.cursor()
 sql = "SELECT * FROM proxy WHERE type=0"
 cur.execute(sql) # 执行sql语句
 results = cur.fetchall() # 获取查询的所有记录
 for row in results:
 head = row[0]
 ip = row[1]
 poxy = row[2]
 if str(head) == 'HTTP':
 self.ls.append(ip + ':' + poxy)
 print('可用{}个代理ip，爬虫开始'.format(len(self.ls)))
 self.crawler_data()
 except Exception as e:
 print(e)

	#爬虫入口，负责构建url
 def crawler_data(self):
 i = 0
 for n in ['投资经理', '土建工程师', '采购', '销售', '运营', 'java', '产品经理', '人力资源', '总经理', 'Python', 'iOS', 'PHP', 'Android',
 'UI设计师', '测试工程师', '自动化测试', '功能测试', '性能测试', '测试开发', '硬件测试', '运维工程师', '系统工程师', '网络工程师', '运维开发', 'DBA',
 '技术经理', '架构师', '技术总监', 'CTO', '技术合伙人', '运维总监', '安全专家', '项目总监',
 'Html5', '产品经理', '网页产品经理', '移动产品经理', '产品助理', '数据产品经理', '游戏策划', '电商产品经理']:
 try:
 while True:
 url = 'https://www.liepin.com/zhaopin/?industryType=&amp;amp;jobKind=&amp;amp;sortFlag=15°radeFlag=0&amp;amp;industries=&amp;amp;salary=&amp;amp;compscale=&amp;amp;key={}&amp;amp;clean_condition=&amp;amp;headckid=4a4adb68b22970bd&amp;amp;d_pageSize=40&amp;amp;siTag=p_XzVCa5J0EfySMbVjghcw~fA9rXquZc5IkJpXC-Ycixw&amp;amp;d_headId=62ac45351cdd7a103ac7d50e1142b2a0&amp;amp;d_ckId=62ac45351cdd7a103ac7d50e1142b2a0&amp;amp;d_sfrom=search_fp&amp;amp;d_curPage=0&amp;amp;curPage={}'.format(
 n, random.randint(1, 20))
 self.request_job_list(url)
 print(url)
 i = i + 1
 if i == 10:
 i = 0
 break
 except Exception as e:
 print(e)
 self.emial()

	#接受传递来的url 进行解析页面数据，传递数据给下一个函数
 def request_job_list(self, url):
 try:
 print(url)
 headers = {
 'Referer': 'https://www.liepin.com/',
 'User-Agent': random.choice(self.USER_AGENTS)
 }
 reponse = requests.get(url, proxies={'http': random.choice(self.ls)}, headers=headers, timeout=5)
 ret = random.uniform(0, 2)
 time.sleep(ret)
 pattern = re.compile('&lt;div class="job-info">'
 '.*?&lt;h3.*?title="(.*?)">.*?&lt;a href="(.*?)" .*?title="(.*?)">.*?&lt;/a>&lt;p class="company-name">&lt;a href="(.*?)" .*?title="(.*?)">.*?&amp;gt;(.*?)&lt;/a>.*?&lt;/p></description></item><item><title>Socket向服务端发送数据（Python）</title><link>https://pangyd.com/post/216-socket-python/</link><pubDate>Sat, 13 Jul 2019 08:58:19 +0800</pubDate><guid>https://pangyd.com/post/216-socket-python/</guid><description>&lt;pre lay-lang="Python" class="layui-code" skin="notepad">import socket
def soct(str_r):
 try:
 address = ('ip', 端口)
 client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 client.connect(address) 
 client.sendall(kk.encode()) #发送数据
 client.settimeout(10) #设置超时时间
 client.close()
 except Exception as e:
 return "失败 "+str(e)
&lt;/pre></description></item><item><title>在Hadoop HDFS NameNode web端中下载文件会重定向到localhost:50075</title><link>https://pangyd.com/post/215-hadoop-hdfs-namenode-weblocalhost-50075/</link><pubDate>Wed, 10 Jul 2019 08:46:58 +0800</pubDate><guid>https://pangyd.com/post/215-hadoop-hdfs-namenode-weblocalhost-50075/</guid><description>&lt;p>host文件在错误的IP地址上指定，则获取并报告环回适配器的地址。因此需要检查一下几项&lt;/p>&lt;p>1.检查hosts文件，确认127.0.0.1对应的是 localhost&lt;/p>&lt;p>2.检查&lt;span>HDFS-site.xml中dfs.name.rpc-address和dfs.datanode.http.address中配置的主机名是否和/etc/hostname中的主机名对应&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p></description></item><item><title>Hadoop 当中 Datanode节点不启动的解决办法</title><link>https://pangyd.com/post/214-hadoop-datanode/</link><pubDate>Sat, 06 Jul 2019 08:35:41 +0800</pubDate><guid>https://pangyd.com/post/214-hadoop-datanode/</guid><description>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;/p>&lt;p>&lt;/p>&lt;pre lay-lang="HTML" class="layui-code" skin="notepad">2019-03-28 08:31:49,347 WARN org.apache.hadoop.hdfs.server.common.Storage: Failed to add storage directory [DISK]file:/opt/hadoop-repo/data/
java.io.IOException: Incompatible clusterIDs in /opt/hadoop-repo/data: namenode clusterID = CID-50b8afea-9e44-4363-970d-4a40917d968a; datanode clusterID = CID-865e7596-297e-4d6a-a997-afec3be712e9
	at org.apache.hadoop.hdfs.server.datanode.DataStorage.doTransition(DataStorage.java:777)
	at org.apache.hadoop.hdfs.server.datanode.DataStorage.loadStorageDirectory(DataStorage.java:300)
	at org.apache.hadoop.hdfs.server.datanode.DataStorage.loadDataStorage(DataStorage.java:416)
	at org.apache.hadoop.hdfs.server.datanode.DataStorage.addStorageLocations(DataStorage.java:395)
	at org.apache.hadoop.hdfs.server.datanode.DataStorage.recoverTransitionRead(DataStorage.java:573)
	at org.apache.hadoop.hdfs.server.datanode.DataNode.initStorage(DataNode.java:1393)
	at org.apache.hadoop.hdfs.server.datanode.DataNode.initBlockPool(DataNode.java:1358)
	at org.apache.hadoop.hdfs.server.datanode.BPOfferService.verifyAndSetNamespaceInfo(BPOfferService.java:313)
	at org.apache.hadoop.hdfs.server.datanode.BPServiceActor.connectToNNAndHandshake(BPServiceActor.java:216)
	at org.apache.hadoop.hdfs.server.datanode.BPServiceActor.run(BPServiceActor.java:637)
	at java.lang.Thread.run(Thread.java:748)&lt;/pre>&lt;p>直接删除数据节点DataNode的current文件夹，即可启动&lt;/p>&lt;p>&lt;/p>&lt;p>&lt;/p></description></item><item><title>如果代码按行付费，会有什么好玩的事情发生？</title><link>https://pangyd.com/post/213/</link><pubDate>Thu, 28 Mar 2019 16:09:54 +0800</pubDate><guid>https://pangyd.com/post/213/</guid><description>&lt;p>&lt;strong>&lt;span>程序员联盟发布了一条消息：&lt;/span>&lt;/strong>&lt;span>以后我们的代码要&lt;span>按行收费&lt;/span>。客户们立即就炸了锅，按代码收费？那你程序员不是想怎么写就怎么写，我们让你们做个项目，你写个空行，写点注释什么的，谁来管?&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;/p>&lt;p>&lt;img data-type="gif" data-src="https://pangyd.com/uploads/2019/03/74c10f869f038762.gif" class=" __bg_gif" data-ratio="1" data-w="300" _width="100%" src="https://pangyd.com/uploads/2019/03/74c10f869f038762.gif" data-order="1" data-fail="0">&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;br>&lt;/p>&lt;p>&lt;strong>&lt;span>物竞天择。&lt;/span>&lt;/strong>&lt;span>有人有需求就立即有人响应。正当这些客户无所适从的时候，一个职业产生了：代码缩行师。客户在审查项目交付的时候会先去缩行事务所请一位缩行师。缩行师的职责就是，在保证不改变原有系统功能的前提下，将程序最大程度的缩减行数，缩行师按照缩减行数的百分之
 10 收费。&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;strong>&lt;span>缩行师&lt;/span>&lt;/strong>&lt;/span>&lt;span>是程序员最大的天敌。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;img data-type="gif" data-src="https://pangyd.com/uploads/2019/03/74c10f869f038762.gif" class=" __bg_gif" data-ratio="0.564" data-w="500" src="https://pangyd.com/uploads/2019/03/74c10f869f038762.gif" data-order="2" data-fail="0">&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>缩行师也是分等级的，最低级的缩行师只能缩缩空行，挪一挪括号，一般人都能做，大抵是被程序员看不起的，往上一级就要稍微懂一点编程知识了，知道怎么把定义的变量合到一行，怎么去掉可以去掉的括号，他们已经一脚踏入了领域和空间的境界了，他们许多是程序员做不下去为了生计讨口饭吃，倘若搞好客户关系，也能活的很滋润。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>再往上一级，这些人是缩行师界的精英，而且随时可以成为最优秀的程序员，他们把无聊的体力工作交给下边的人去做，自己则和程序员斗智斗勇，“你这个变量没必要定义”，“你这两处的功能重复了，回去重构一下”，“你这个是自己造轮子，去找别人开源写好的”。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>他们有的曾经是最好的程序员，有的是因为忍受不了缩行师的百般挑刺，无奈转行，有的是因为满足内心找茬的欲望。他们有的是从事多年的缩行师，从学徒起一步一步坐起，扎扎实实的走到现在的地位，这个级别的缩行师是各大缩行事务所争抢的对象。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;/p>&lt;p>&lt;img data-type="gif" data-src="https://pangyd.com/uploads/2019/03/74c10f869f038762.gif" class=" __bg_gif" data-ratio="0.546" data-w="500" src="https://pangyd.com/uploads/2019/03/74c10f869f038762.gif" data-order="3" data-fail="0">&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>每个客户都以邀请到他们为荣，预约的人多了，事务所开始准备&lt;strong>“缩号”&lt;/strong>，客户只有摇到了缩号才能有幸邀请到这些人，有的客户更是为专家缩号大打出手，于是又催生了一种叫&lt;strong>“缩牛”&lt;/strong>的职业，不再赘述。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>他们某种程度上已经达到了缩行师的顶峰，但还有一种传说中的存在，他们是打破规则的存在，如果你侥幸看到他们的杰作，你就会发现上面提到的都是浮云。一行，只需要一行就够了，什么工程，什么项目，只需要一行。jQuery.min.js 就是他们的杰作。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>有一个站在巅峰的男人曾经应拉里
 · 佩奇的邀请将谷歌的所有代码写成了一行，并且能完整的实现了谷歌现有的所有功能，人们甚至发现谷歌搜索快了将近 
30%。后来有华尔街和硅谷的资深从业者看到这行代码后久久不能平静，对这行代码给出了 5600 
亿美元的估值，当然这行代码一般人是看不完的，据说这行代码的长度可以从加州连接到 M31 星系。&lt;/span>&lt;/p>&lt;p>&lt;span>程序员的生活变得越来越艰难，程序员联盟本身的福祉：变成了灾难，尽管随着代码的行数减少，单行的价格在不断的升高，程序员行业的整体质量也在不断的提高，但依旧艰难。程序员联盟又做了一个艰难的决定：最终的代码每行不得多于
 200 字符。对于一般的程序，一行 200 字符足够了，即使一行内容长，也可以分行解决。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;/p>&lt;p>&lt;img data-type="gif" data-src="https://pangyd.com/uploads/2019/03/74c10f869f038762.gif" class=" __bg_gif" data-ratio="0.75" data-w="800" src="https://pangyd.com/uploads/2019/03/74c10f869f038762.gif" data-order="4" data-fail="0">&lt;/p></description></item><item><title>利用Python和Selenium使酒店Wifi免费</title><link>https://pangyd.com/post/212-pythonseleniumwifi/</link><pubDate>Fri, 22 Mar 2019 13:08:55 +0800</pubDate><guid>https://pangyd.com/post/212-pythonseleniumwifi/</guid><description>&lt;p align="left">最近我休年假了，并决定在假期去拜访朋友。我在一家旅馆住了几天，令我惊讶的是，酒店的wifi收费。这在2018年，你能想象吗？&lt;/p>&lt;p align="left">他们也不是那么冷酷。你看，这些慷慨的人让你用wifi20分钟。整整20分钟。这几乎是Minecraft视频的一半。&lt;/p>&lt;p align="left">如果他们让每个设备在有限的时间内使用互联网，必须有识别每个设备的方法。路由器通过设备的MAC地址来区分设备。幸运的是，我们可以很容易地改变我们的MAC地址。&lt;/p>&lt;p align="left">使用macchanger&lt;/p>&lt;p align="left">有一个非常有用的命令行工具，叫做macchanger。它允许你手动更改、随机化和恢复设备的MAC地址。这里是想定期随机化我们的MAC（每20分钟），以便无限期地使用免费Wifi。&lt;/p>&lt;p align="left">需要运行3个小命令。这是必需的，因为当网络接口连接到路由器时，macchanger无法工作。&lt;/p>&lt;p align="left">&lt;img src="https://pangyd.com/uploads/2019/03/7440792922ad4819.png" alt="">&lt;/p>&lt;p align="left">在上面的命令中，wlp3s0是我的网络接口的名称。你可以通过运行&lt;span>ip a&lt;/span>找到你的网络接口的名称。如果你运行这些命令，可以启动浏览器，然后你会看到要求你付费或试用20分钟的页面。时间结束后，你可以再次运行命令并继续执行。&lt;/p>&lt;p align="left">但这是体力劳动，每小时做3次太重复了。嗯。自动化重复内容的好工具是什么？&lt;/p>&lt;p align="left">使用Selenium&lt;/p>&lt;p align="left">首先，不使用这些命令。使用os模块，我们可以从脚本运行macchanger。&lt;/p>&lt;p align="left">&lt;/p></description></item><item><title>国赛选拔赛第三名</title><link>https://pangyd.com/post/4/</link><pubDate>Sun, 03 Mar 2019 22:18:55 +0800</pubDate><guid>https://pangyd.com/post/4/</guid><description>&lt;div class="gallery" style="display:grid;gap:.75rem;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));margin:1.5rem 0">

 &lt;figure style="margin:0">
 &lt;img src="https://pangyd.com/uploads/2020/03/221f385d5c55b5e3.jpg" alt="" loading="lazy" decoding="async" width="640" height="480" style="border-radius:6px">
 &lt;/figure>

 &lt;figure style="margin:0">
 &lt;img src="https://pangyd.com/uploads/2020/03/4586b5f340edbf1d.jpg" alt="" loading="lazy" decoding="async" width="640" height="480" style="border-radius:6px">
 &lt;/figure>


&lt;/div></description></item><item><title>Java实现冒泡排序</title><link>https://pangyd.com/post/211-java/</link><pubDate>Sat, 16 Feb 2019 10:38:10 +0800</pubDate><guid>https://pangyd.com/post/211-java/</guid><description>&lt;p>&lt;strong>冒泡排序：&lt;/strong>&lt;/p>&lt;p>利用冒泡排序对数组进行排序&lt;/p>&lt;p>&lt;strong>基本概念：&lt;/strong>&lt;/p>&lt;p>依次比较相邻的两个数，将小数放在前面，大数放在后面。即在第一趟：首先比较第1个和第2个数，将小数放前，大数放后。然后比较第2个数和第3个数，将小数放前，大数放后，如此继续，直至比较最后两个数，将小数放前，大数放后。至此第一趟结束，将最大的数放到了最后。在第二趟：仍从第一对数开始比较（因为可能由于第2个数和第3个数的交换，使得第1个数不再小于第2个数），将小数放前，大数放后，一直比较到倒数第二个数（倒数第一的位置上已经是最大的），第二趟结束，在倒数第二的位置上得到一个新的最大数（其实在整个数列中是第二大的数）。如此下去，重复以上过程，直至最终完成排序。&lt;/p>&lt;p>&lt;b>代码如下：&lt;/b>&lt;/p>&lt;pre lay-lang="Java" class="layui-code" skin="notepad">&lt;p>&lt;b>package 冒泡排序;
import java.util.Arrays;
&lt;p>public class BubbleSort1 {
public static void BubbleSort(int[] arr) {
boolean flag = true;
while(flag){
int temp;//定义一个临时变量
for(int i=0;i&amp;lt;arr.length-1;i++){//冒泡趟数，n-1趟
for(int j=0;j&amp;lt;arr.length-i-1;j++){
if(arr[j+1]&amp;lt;arr[j]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
flag = true;
}
}
if(!flag){
break;//若果没有发生交换，则退出循环
}
}
}
}
public static void main(String[] args) {
int arr[] = new int[]{1,6,2,2,5};
BubbleSort.BubbleSort(arr);
System.out.println(Arrays.toString(arr));
}
}&lt;/b>&lt;/p>&lt;/pre>&lt;p>&lt;/p>&lt;/p></description></item><item><title>省赛一等奖</title><link>https://pangyd.com/post/3/</link><pubDate>Sat, 29 Dec 2018 22:14:25 +0800</pubDate><guid>https://pangyd.com/post/3/</guid><description>&lt;div class="gallery" style="display:grid;gap:.75rem;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));margin:1.5rem 0">

 &lt;figure style="margin:0">
 &lt;img src="https://pangyd.com/uploads/2020/03/793f7dc42855d8ea.jpg" alt="" loading="lazy" decoding="async" width="640" height="480" style="border-radius:6px">
 &lt;/figure>

 &lt;figure style="margin:0">
 &lt;img src="https://pangyd.com/uploads/2020/03/7a70fdb8f2360df8.jpg" alt="" loading="lazy" decoding="async" width="640" height="480" style="border-radius:6px">
 &lt;/figure>

 &lt;figure style="margin:0">
 &lt;img src="https://pangyd.com/uploads/2020/03/e247834dee7d3305.jpg" alt="" loading="lazy" decoding="async" width="640" height="480" style="border-radius:6px">
 &lt;/figure>

 &lt;figure style="margin:0">
 &lt;img src="https://pangyd.com/uploads/2020/03/24cc2d1ca8ad3a47.jpg" alt="" loading="lazy" decoding="async" width="640" height="480" style="border-radius:6px">
 &lt;/figure>


&lt;/div></description></item><item><title>正则测试器-RegExTester_JavaScript</title><link>https://pangyd.com/post/210-regextester-javascript/</link><pubDate>Thu, 29 Nov 2018 10:40:19 +0800</pubDate><guid>https://pangyd.com/post/210-regextester-javascript/</guid><description>&lt;p>&lt;a target="_blank" href="https://pangyd.com/zl/web/regextester.html">点击测试&lt;/a>&lt;br>&lt;/p></description></item><item><title>Python 中的单例模式</title><link>https://pangyd.com/post/209-python/</link><pubDate>Sun, 11 Nov 2018 08:35:05 +0800</pubDate><guid>https://pangyd.com/post/209-python/</guid><description>&lt;pre>&lt;code class="language-python hljs">&lt;ol class="hljs-ln">&lt;li>&lt;h2 id="单例模式">单例模式&lt;/h2>

&lt;p>&lt;b>单例模式（Singleton Pattern）&lt;/b>是一种常用的软件设计模式，该模式的主要目的是&lt;b>确保某一个类只有一个实例存在&lt;/b>。当你希望在整个系统中，某个类只能出现一个实例时，单例对象就能派上用场。&lt;/p>

&lt;p>比如，某个服务器程序的配置信息存放在一个文件中，客户端通过一个 AppConfig 
的类来读取配置文件的信息。如果在程序运行期间，有很多地方都需要使用配置文件的内容，也就是说，很多地方都需要创建 AppConfig 
对象的实例，这就导致系统中存在多个 AppConfig 的实例对象，而这样会严重浪费内存资源，尤其是在配置文件内容很多的情况下。事实上，类似 
AppConfig 这样的类，我们希望在程序运行期间只存在一个实例对象。&lt;/p>

&lt;p>在 Python 中，我们可以用多种方法来实现单例模式：&lt;/p>

&lt;ul>
&lt;li>使用模块&lt;/li>
&lt;li>使用 __new__&lt;/li>
&lt;li>使用装饰器（decorator）&lt;/li>
&lt;/ul>

&lt;h2 id="使用模块">&lt;a name="t1">&lt;/a>使用模块&lt;/h2>

&lt;p>其实，Python 的模块就是天然的单例模式，因为模块在第一次导入时，会生成 .pyc 文件，当第二次导入时，就会直接加载 .pyc 
文件，而不会再次执行模块代码。因此，我们只需把相关的函数和数据定义在一个模块中，就可以获得一个单例对象了。如果我们真的想要一个单例类，可以考虑这样做：&lt;/p>

&lt;pre class="prettyprint" name="code">&lt;code class="hljs python has-numbering">&lt;span class="hljs-comment"># mysingleton.py&lt;/span>
&lt;span class="hljs-class">&lt;span class="hljs-keyword">class&lt;/span> &lt;span class="hljs-title">My_Singleton&lt;/span>&lt;span class="hljs-params">(object)&lt;/span>:&lt;/span>
 &lt;span class="hljs-function">&lt;span class="hljs-keyword">def&lt;/span> &lt;span class="hljs-title">foo&lt;/span>&lt;span class="hljs-params">(self)&lt;/span>:&lt;/span>
 &lt;span class="hljs-keyword">pass&lt;/span>

my_singleton = My_Singleton()&lt;/code>&lt;/pre>
&lt;p>将上面的代码保存在文件 mysingleton.py 中，然后这样使用：&lt;/p>
&lt;pre class="prettyprint" name="code">&lt;code class="hljs python has-numbering">&lt;span class="hljs-keyword">from&lt;/span> mysingleton &lt;span class="hljs-keyword">import&lt;/span> my_singleton

my_singleton.foo()&lt;/code>&lt;/pre>
&lt;h2 id="使用-new">&lt;a name="t2">&lt;/a>使用 __new__&lt;/h2>
&lt;p>为了使类只能出现一个实例，我们可以使用 __new__ 来控制实例的创建过程，代码如下：&lt;/p>
&lt;pre class="prettyprint" name="code">&lt;code class="hljs python has-numbering">&lt;span class="hljs-class">&lt;span class="hljs-keyword">class&lt;/span> &lt;span class="hljs-title">Singleton&lt;/span>&lt;span class="hljs-params">(object)&lt;/span>:&lt;/span>
 _instance = &lt;span class="hljs-keyword">None&lt;/span>
 &lt;span class="hljs-function">&lt;span class="hljs-keyword">def&lt;/span> &lt;span class="hljs-title">__new__&lt;/span>&lt;span class="hljs-params">(cls, *args, **kw)&lt;/span>:&lt;/span>
 &lt;span class="hljs-keyword">if&lt;/span> &lt;span class="hljs-keyword">not&lt;/span> cls._instance:
 cls._instance = super(Singleton, cls).__new__(cls, *args, **kw) 
 &lt;span class="hljs-keyword">return&lt;/span> cls._instance 

&lt;span class="hljs-class">&lt;span class="hljs-keyword">class&lt;/span> &lt;span class="hljs-title">MyClass&lt;/span>&lt;span class="hljs-params">(Singleton)&lt;/span>:&lt;/span> 
 a = &lt;span class="hljs-number">1&lt;/span>&lt;/code>&lt;/pre>
&lt;p>在上面的代码中，我们将类的实例和一个类变量 _instance 关联起来，如果 cls._instance 为 None 则创建实例，否则直接返回 cls._instance。&lt;/p></description></item><item><title>人生苦短,我用python “Life is short. You need Python.”</title><link>https://pangyd.com/post/207-python-life-is-short-you-need-python/</link><pubDate>Fri, 09 Nov 2018 08:22:51 +0800</pubDate><guid>https://pangyd.com/post/207-python-life-is-short-you-need-python/</guid><description>&lt;p>&lt;img src="https://pangyd.com/uploads/2018/09/f0c1d12340235ebb.jpg" alt="index.jpg">&lt;/p>&lt;p>&lt;span>&lt;span>Python 在约 40 年前出现，现在已经有数以千计基于这项技术的网站和软件项目。Python 因其独有的特点从众多开发语言中脱颖而出，深受世界各地的开发者喜爱。&lt;/span>&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;span>正文共：4565 字&amp;nbsp;&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;span>预计阅读时间：12 分钟&lt;/span>&lt;/p>&lt;p>人生苦短， 我用 Python ，不知道从什么时候开始，这句话开始流行。&lt;/p>&lt;p>&lt;img title="" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" alt="640?wx_fmt=jpeg&amp;wxfrom=5&amp;wx_lazy=1" border="0">&lt;/p>&lt;p>人们可能会说， 2017 年是 Python 辉煌的一年。毕竟在这一年中，Python 的增长速度令人惊艳。&lt;/p>&lt;p>&lt;img title="" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" alt="640?wx_fmt=jpeg&amp;wxfrom=5&amp;wx_lazy=1" border="0">&lt;/p>&lt;p style="text-align: center">&lt;span>主要编程语言的增长趋势，图片来自 Stack Overflow&lt;/span>&lt;/p>&lt;p>在GitHub 2017年度报告中，Python 超越 Java 成第二受欢迎语言。在 ranked.com 的排名中，Python 是 2017 年最受欢迎人工智能编程语言（第二是 C++，R 并未上榜）。&lt;/p>&lt;p>根据 Stack Overflow 流量统计，2017 年 6 月，Python 第一次成为高收入国家 Stack Overflow 访问量最大的标签。&lt;/p>&lt;p>&lt;img class="img_loading" title="" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" alt="640?wx_fmt=jpeg" border="0">&lt;/p>&lt;p>在 TIOBE 2018 年 4 月编程语言排行榜前 20 名中，Python 已跃居到第四位，前三分别为为 Java ，C、C++。&lt;/p></description></item><item><title>re正则模块详解</title><link>https://pangyd.com/post/206-re/</link><pubDate>Wed, 07 Nov 2018 08:10:45 +0800</pubDate><guid>https://pangyd.com/post/206-re/</guid><description>&lt;p>re正则表达式是一种工具，和其他工具一样，它是人们为了解决某一类专门的问题而发明的。想要理解正则表达式及其功用。最好的办法是了解他们可以解决什么样的问题&lt;/p>&lt;p>正则表达式的主要用途之一是搜索变化多端的文本，比如，搜索以http开头的 以句号等空白字结尾的字符串&amp;nbsp;&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;/p>&lt;pre lay-lang="Python" class="layui-code" skin="notepad">import re
&lt;p>text = &amp;ldquo;The Attila the Hun Show&amp;rdquo;&lt;/p>
&lt;h1 id="a-single-character-单个字符">a single character 单个字符&lt;/h1>
&lt;p>m = re.match(&amp;quot;.&amp;quot;, text)
if m: print repr(&amp;quot;.&amp;quot;), &amp;ldquo;=&amp;gt;&amp;rdquo;, repr(m.group(0))&lt;/p>
&lt;h1 id="any-string-of-characters-任何字符串">any string of characters 任何字符串&lt;/h1>
&lt;p>m = re.match(&amp;quot;.&lt;em>&amp;quot;, text)
if m: print repr(&amp;quot;.&lt;/em>&amp;quot;), &amp;ldquo;=&amp;gt;&amp;rdquo;, repr(m.group(0))&lt;/p>
&lt;h1 id="a-string-of-letters-at-least-one-只包含字母的字符串至少一个">a string of letters (at least one) 只包含字母的字符串(至少一个)&lt;/h1>
&lt;p>m = re.match(&amp;quot;\w+&amp;quot;, text)
if m: print repr(&amp;quot;\w+&amp;quot;), &amp;ldquo;=&amp;gt;&amp;rdquo;, repr(m.group(0))&lt;/p>
&lt;h1 id="a-string-of-digits-只包含数字的字符串">a string of digits 只包含数字的字符串&lt;/h1>
&lt;p>m = re.match(&amp;quot;\d+&amp;quot;, text)
if m: print repr(&amp;quot;\d+&amp;quot;), &amp;ldquo;=&amp;gt;&amp;rdquo;, repr(m.group(0))&lt;/p></description></item><item><title>IT程序员被叫“码农”程序员你怎么看？</title><link>https://pangyd.com/post/205-it/</link><pubDate>Tue, 06 Nov 2018 14:07:36 +0800</pubDate><guid>https://pangyd.com/post/205-it/</guid><description>&lt;p style="text-align: start">在几年之前，”码农“还只是行业内大家互相调侃的称谓，感觉现在几乎所有行业的人都喊IT工程师“码农”。“码农”反而成为了官方称呼了。感觉这不是一个好事，影响学生们对这个行业的看法，感觉好学校的学生都不愿意做技术了。技术大拿们该不该号召大家不要再以码农自称了？&lt;/p>&lt;p style="text-align: start">&lt;br>&lt;/p>&lt;p style="text-align: start">预料之内，这个话题引来众多程序员的讨论，下面摘选了10个比较有代（有）表（意）性（思）的回答：&lt;/p>&lt;p style="text-align: center">&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-size="700|569">&lt;/p>&lt;p style="text-align: justify">&lt;br>&lt;/p>&lt;p style="text-align: justify">&lt;span>程序员一：&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>歧视农名是不对的！&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>程序员二：&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>“码农”比“码畜”好听多了。&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>程序员三：&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>你多给我一倍薪水，叫我孙子都行。&lt;br>&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;br>&lt;/p>&lt;p style="text-align: justify">&lt;span>程序员四：&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>我们好歹还是人，产品和设计已经是狗了。&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;br>&lt;/p>&lt;p style="text-align: justify">&lt;span>程序员五：&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>码农算是好的，硅工是我等打磨芯片的民工的昵称。&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;br>&lt;/p>&lt;p style="text-align: justify">&lt;span>程序员六：&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>一位长者告诉我们“中国有句古话,叫做闷声发大财。”&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>程序员七：&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>这有什么？有些人还巴不得大家都说他是人民公仆呢。&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;br>&lt;/p>&lt;p style="text-align: justify">&lt;span>程序员八：&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>我们公司的美术还管我叫做“打字员”呢，满满的恶意啊&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>程序员九：&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>我们每天研究技术，哪有心思管这些，小屁孩们爱来不来。现在码农工资节节高升，正说明了人还不够。等人太多了，工资就会下跌，到时候我们就知道中国需要多少码农了。&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>程序员十：&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>一年工作经验的java程序员在北京可以拿到8k+以上（保守估计），码农通常智力都不低，少数码农有交际困难，不过多数都没有。这么一群高收入高智力的人群会被人鄙视？别闹了，我们只是自嘲而已，真的有哪个文科生来嘲笑我们，我们绝对会不择手段的在各个方面碾压过去的。trust
 me&lt;/span>&lt;/p></description></item><item><title>python的redis简单使用</title><link>https://pangyd.com/post/203-pythonredis/</link><pubDate>Mon, 05 Nov 2018 06:54:40 +0800</pubDate><guid>https://pangyd.com/post/203-pythonredis/</guid><description>&lt;p>安装的Python版本&amp;nbsp;3.6.1&lt;/p>
&lt;p>redis安装的2.8&lt;/p>
&lt;p>安装redis模块&lt;/p>
&lt;div class="cnblogs_code">
&lt;pre>pip install redis&lt;/pre>
&lt;/div>
&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" alt="">&lt;/p>
&lt;p>简单使用&lt;/p>
&lt;p>redis-test.py&lt;/p>
&lt;div class="cnblogs_code">
&lt;pre>&lt;span>import&lt;/span>&lt;span> redis
r&lt;/span>=redis.Redis(host=&lt;span>'&lt;/span>&lt;span>127.0.0.1&lt;/span>&lt;span>'&lt;/span>,port=6609,db=&lt;span>0)
r.set(&lt;/span>&lt;span>'&lt;/span>&lt;span>name&lt;/span>&lt;span>'&lt;/span>,&lt;span>'&lt;/span>&lt;span>baby&lt;/span>&lt;span>'&lt;/span>&lt;span>)
&lt;/span>&lt;span>print&lt;/span>(r.get(&lt;span>'&lt;/span>&lt;span>name&lt;/span>&lt;span>'&lt;/span>&lt;span>))
&lt;/span>&lt;span>print&lt;/span>(r.dbsize())&lt;/pre>
&lt;/div>
&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" alt="">&lt;/p>
&lt;p>使用connection pool来管理对一个redis server的所有连接，避免每次建立、释放连接的开销。&lt;/p>
&lt;p>默认，每个Redis实例都会维护一个自己的连接池。&lt;/p>
&lt;p>可以直接建立一个连接池，然后作为参数 Redis，这样就可以实现多个Redis实例共享一个连接池&lt;/p>
&lt;p>使用连接池&lt;/p>
&lt;div class="cnblogs_code">
&lt;pre> &lt;span>import&lt;/span>&lt;span> redis
 pool &lt;/span>= redis.ConnectionPool(host=&lt;span>'&lt;/span>&lt;span>127.0.0.1&lt;/span>&lt;span>'&lt;/span>,port=6609&lt;span>)
 r &lt;/span>= redis.Redis(connection_pool=&lt;span>pool)
 r.set(&lt;/span>&lt;span>'&lt;/span>&lt;span>name1&lt;/span>&lt;span>'&lt;/span>,&lt;span>'&lt;/span>&lt;span>lili&lt;/span>&lt;span>'&lt;/span>&lt;span>)
 &lt;/span>&lt;span>print&lt;/span>(r.get(&lt;span>'&lt;/span>&lt;span>name1&lt;/span>&lt;span>'&lt;/span>))&lt;/pre>
&lt;/div>
&lt;p>&amp;nbsp;&lt;/p>
&lt;p>应用：页面点击数&lt;/p>
&lt;p>　　需要对一系列页面记录点击次数，如果使用关系数据库来存储点击，可能存在大量的行级锁争用&lt;/p>
&lt;p>　　(1)当redis服务器启动时，可以从关系数据库读入点击数的初始值&lt;/p>
&lt;div class="cnblogs_code">
&lt;pre>&lt;span>import&lt;/span>&lt;span> redis
r&lt;/span>=redis.Redis(host=&lt;span>'&lt;/span>&lt;span>127.0.0.1&lt;/span>&lt;span>'&lt;/span>,port=6609,db=&lt;span>0)
r.set(&lt;/span>&lt;span>'&lt;/span>&lt;span>visits:100&lt;/span>&lt;span>'&lt;/span>,999)&lt;/pre>
&lt;/div>
&lt;p>　　(2)有人访问页面时&lt;/p>
&lt;div class="cnblogs_code">
&lt;pre>r.incr(&lt;span>'&lt;/span>&lt;span>visits:100&lt;/span>&lt;span>'&lt;/span>)&lt;/pre>
&lt;/div>
&lt;p>　　(3)获取页面点击数&lt;/p>
&lt;div class="cnblogs_code">
&lt;pre>r.get(&lt;span>'&lt;/span>&lt;span>visits:100&lt;/span>&lt;span>'&lt;/span>)&lt;/pre>
&lt;/div>
&lt;p>Pipeline 是 StrictRedis 类的子类，支持在一个请求里发送缓冲的多个命令。通过减少客户端和服务器之间往来的数据包，可以大大提高命令组的性能&lt;/p>
&lt;p>简单使用&lt;/p>
&lt;div class="cnblogs_code">
&lt;pre>&amp;gt;&amp;gt;&amp;gt;&lt;span>import&lt;/span>&lt;span> redis 
&lt;/span>&amp;gt;&amp;gt;&amp;gt;r=redis.Redis(host=&lt;span>'&lt;/span>&lt;span>127.0.0.1&lt;/span>&lt;span>'&lt;/span>,port=6609,db=&lt;span>0)
&lt;/span>&amp;gt;&amp;gt;&amp;gt; r.set(&lt;span>'&lt;/span>&lt;span>name&lt;/span>&lt;span>'&lt;/span>, &lt;span>'&lt;/span>&lt;span>baby&lt;/span>&lt;span>'&lt;/span>&lt;span>)
&lt;/span>&amp;gt;&amp;gt;&amp;gt; pipe =&lt;span> r.pipeline()
&lt;/span>&amp;gt;&amp;gt;&amp;gt; pipe.set(&lt;span>'&lt;/span>&lt;span>birthday&lt;/span>&lt;span>'&lt;/span>, &lt;span>'&lt;/span>&lt;span>2010&lt;/span>&lt;span>'&lt;/span>&lt;span>)
&lt;/span>&amp;gt;&amp;gt;&amp;gt; pipe.get(&lt;span>'&lt;/span>&lt;span>name&lt;/span>&lt;span>'&lt;/span>&lt;span>)
&lt;/span>&amp;gt;&amp;gt;&amp;gt; pipe.execute()&lt;/pre>
&lt;/div>
&lt;p>为了方便使用，所有缓冲到 pipeline 的命令返回 pipeline 对象本身&lt;/p></description></item><item><title>Python---命名空间与作用域</title><link>https://pangyd.com/post/202-python/</link><pubDate>Tue, 30 Oct 2018 17:03:10 +0800</pubDate><guid>https://pangyd.com/post/202-python/</guid><description>&lt;h4 id="1-命名空间">1. 命名空间&lt;/h4>
&lt;h5 id="11-什么是命名空间">1.1 什么是命名空间&lt;/h5>
&lt;p>&lt;code>Namespace&lt;/code>命名空间，也称名字空间，是从名字到对象的映射。&lt;code>Python&lt;/code>中，大部分的命名空间都是由字典来实现的，但是本文的不会涉及命名空间的实现。&lt;/p>
&lt;p>命名空间的一大作用是避免名字冲突：&lt;/p>
&lt;pre class="prettyprint" name="code">&lt;code class="language-python hljs has-numbering">&lt;span class="hljs-function">&lt;span class="hljs-keyword">def&lt;/span> &lt;span class="hljs-title">fun1&lt;/span>&lt;span class="hljs-params">()&lt;/span>:&lt;/span>
 i = &lt;span class="hljs-number">1&lt;/span>

&lt;span class="hljs-function">&lt;span class="hljs-keyword">def&lt;/span> &lt;span class="hljs-title">fun2&lt;/span>&lt;span class="hljs-params">()&lt;/span>:&lt;/span>
 i = &lt;span class="hljs-number">2&lt;/span>&lt;/code>&lt;/pre>
&lt;p>同一个模块中的两个函数中，两个同名名字&lt;code>i&lt;/code>之间绝没有任何关系，因为它们分属于不同明明空间。&lt;/p>
&lt;h5 id="12-命名空间的种类">1.2 命名空间的种类&lt;/h5>
&lt;p>常见的命名空间有：&lt;/p>
&lt;ul>&lt;li>&lt;p>&lt;code>built-in&lt;/code>名字集合，包括像&lt;code>abs()&lt;/code>这样的函数，以及内置的异常名字等。通常，使用&lt;strong>内置&lt;/strong>这个词表示这个命名空间-&lt;strong>内置命名空间&lt;/strong>&lt;/p>&lt;/li>&lt;li>&lt;p>模块全局名字集合，直接定义在模块中的名字，如类，函数，导入的其他模块等。通常，使用&lt;strong>全局命名空间&lt;/strong>表示。&lt;/p>&lt;/li>&lt;li>&lt;p>函数调用过程中的名字集合，函数中的参数，函数体定义的名字等，在函数调用时被“激活”，构成了一个命名空间。通常，使用&lt;strong>局部命名空间&lt;/strong>表示。&lt;/p>&lt;/li>&lt;li>&lt;p>一个对象的属性集合，也构成了一个命名空间。但通常使用&lt;code>objname.attrname&lt;/code>的间接方式访问属性，而不是直接访问，故不将其列入命名空间讨论。&lt;/p>&lt;/li>&lt;li>&lt;p>类定义的命名空间，通常解释器进入类定义时，即执行到&lt;code>class ClassName:&lt;/code>语句，会新建一个命名空间。(见官方对类定义的&lt;a href="https://docs.python.org/3/tutorial/classes.html#class-definition-syntax" rel="nofollow" target="_blank">说明&lt;/a>)&lt;/p>&lt;/li>&lt;/ul>
&lt;h5 id="13-命名空间的生命周期">1.3 命名空间的生命周期&lt;/h5>
&lt;p>不同类型的命名空间有不同的生命周期：&lt;/p>
&lt;ul>&lt;li>&lt;p>内置命名空间，在&lt;code>Python&lt;/code>解释器启动时创建，解释器退出时销毁；&lt;/p>&lt;/li>&lt;li>&lt;p>全局命名空间，模块的全局命名空间在模块定义被解释器读入时创建，解释器退出时销毁；&lt;/p>&lt;/li>&lt;li>&lt;p>局部命名空间，这里要区分函数以及类定义。函数的局部命名空间，在函数调用时创建，函数返回或者由未捕获的异常时销毁；类定义的命名空间，在解释器读到类定义创建，类定义结束后销毁。(关于类定义的命名空间，在类定义结束后销毁，但其实类对象就是这个命名空间内容的包装，见官方对类定义的&lt;a href="https://docs.python.org/3/tutorial/classes.html#class-definition-syntax" rel="nofollow" target="_blank">说明&lt;/a>)&lt;/p>&lt;/li>&lt;/ul>
&lt;h4 id="2-作用域">2. 作用域&lt;/h4>
&lt;h5 id="21-什么是作用域">2.1 什么是作用域&lt;/h5>
&lt;p>作用域是&lt;code>Python&lt;/code>的一块文本区域，这个区域中，命名空间可以被“直接访问”。这里的直接访问指的是试图在命名空间中找到名字的绝对引用(非限定引用)。这里有必要解释下&lt;strong>直接引用&lt;/strong>和&lt;strong>间接引用&lt;/strong>：&lt;/p>
&lt;ul>&lt;li>&lt;p>直接引用；直接使用名字访问的方式，如&lt;code>name&lt;/code>，这种方式尝试在名字空间中搜索名字&lt;code>name&lt;/code>。&lt;/p>&lt;/li>&lt;li>&lt;p>间接引用；使用形如&lt;code>objname.attrname&lt;/code>的方式，即属性引用，这种方式不会在命名空间中搜索名字&lt;code>attrname&lt;/code>，而是搜索名字&lt;code>objname&lt;/code>，再访问其属性。&lt;/p>&lt;/li>&lt;/ul>
&lt;h5 id="22-与命名空间的关系">2.2 与命名空间的关系&lt;/h5>
&lt;p>现在，命名空间持有了名字。作用域是&lt;code>Python&lt;/code>的一块文本区域，即一块代码区域，需要代码区域引用名字(访问变量)，那么必然作用域与命名空间之间就有了联系。&lt;/p>
&lt;p>顾名思义，名字作用域就是名字可以影响到的代码文本区域，命名空间的作用域就是这个命名空间可以影响到的代码文本区域。那么也存在这样一个代码文本区域，多个命名空间可以影响到它。 &lt;br>
作用域只是文本区域，其定义是静态的；而名字空间却是动态的，只有随着解释器的执行，命名空间才会产生。那么，在静态的作用域中访问动态命名空间中的名字，造成了作用域使用的动态性。&lt;/p>
&lt;p>那么，可以这样认为：&lt;/p>
&lt;blockquote>
 &lt;p>静态的作用域，是一个或多个命名空间按照一定规则叠加影响代码区域；运行时动态的作用域，是按照特定层次组合起来的命名空间。&lt;/p>
&lt;/blockquote>
&lt;p>在一定程度上，可以认为&lt;strong>动态的作用域就是命名空间&lt;/strong>。在后面的表述中，我会把动态的作用域与其对应命名空间等同起来。&lt;/p>
&lt;h5 id="23-名字搜索规则">2.3 名字搜索规则&lt;/h5>
&lt;p>在程序中引用了一个名字，&lt;code>Python&lt;/code>是怎样搜索到这个名字呢？&lt;/p>
&lt;p>在程序运行时，至少存在三个命名空间可以被直接访问的作用域：&lt;/p>
&lt;ul>&lt;li>&lt;p>Local &lt;br>
首先搜索，包含局部名字的最内层（innermost）作用域，如函数/方法/类的内部局部作用域；&lt;/p>&lt;/li>&lt;li>&lt;p>Enclosing &lt;br>
根据嵌套层次从内到外搜索，包含非局部（nonlocal）非全局（nonglobal）名字的任意封闭函数的作用域。如两个嵌套的函数，内层函数的作用域是局部作用域，外层函数作用域就是内层函数的 Enclosing作用域；&lt;/p>&lt;/li>&lt;li>&lt;p>Global &lt;br>
倒数第二次被搜索，包含当前模块全局名字的作用域；&lt;/p>&lt;/li>&lt;li>&lt;p>Built-in &lt;br>
最后被搜索，包含内建名字的最外层作用域。&lt;/p>&lt;/li>&lt;/ul>
&lt;p>程序运行时，&lt;code>LGB&lt;/code>三个作用域是一定存在的，&lt;code>E&lt;/code>作用域不一定存在；若程序是这样的：&lt;/p>
&lt;pre class="prettyprint" name="code">&lt;code class="language-python hljs has-numbering">i = &lt;span class="hljs-number">1&lt;/span>
print(i)&lt;/code>&lt;/pre>
&lt;p>局部作用域在哪里呢？我们认为(&lt;a href="https://docs.python.org/3/tutorial/classes.html#python-scopes-and-namespaces" rel="nofollow" target="_blank">Python Scopes And Namespaces&lt;/a>)：&lt;/p>
&lt;blockquote>
 &lt;p>Usually, the local scope references the local names of the 
(textually) current function. Outside functions, the local scope 
references the same namespace as the global scope: the module’s 
namespace. Class definitions place yet another namespace in the local 
scope.&lt;/p></description></item><item><title>OSI七层模型</title><link>https://pangyd.com/post/201-osi/</link><pubDate>Fri, 12 Oct 2018 11:07:51 +0800</pubDate><guid>https://pangyd.com/post/201-osi/</guid><description>&lt;p>&lt;span>OSI模型是开放系统互连参考模型，为开放式的互连信息提供一种功能的框架。&lt;span>举个栗子，你通过计算机向其他人传递某一个信息的时候，要保证信息正确准确的传递到他的计算机上，就要遵守一定的协议。否则，他的计算机可能就不能识别你的信息。&lt;/span>&lt;/span>&lt;span>这个协议是人为建立的，在1979年国际标准化组织建立了一个分委会来专门研究一种用于开放系统的体系结构，用来定义连接异种计算机的标准主体结构。&lt;/span>&lt;/p>
&lt;p>&lt;span>&lt;/span>&lt;span>同层之间的通信规则和约定被称之为协议。这个协议贯彻了计算的硬件和软件。&lt;/span>&lt;span>&lt;br>&lt;/span>&lt;/p>
&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>
&lt;p>&lt;span>第一层：物理层&lt;/span>&lt;/p>
&lt;h3>&lt;span>为设备之间的信息传输提供可靠环境，那么这个环境是什么呢？&lt;br>
就是如：同轴电缆，插头，接收器，水晶头，网线等。可以在通信的两个数据终端的设备之间连接起来形成一条通路。&lt;br>
再说下这个协议中的某一项规定：比如eiars-232-c及rs-449就可以兼容于100序列线上。&lt;/span>&lt;/h3>
&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>
&lt;p>&lt;span>第二层：数据链路层&lt;/span>&lt;/p>
&lt;p>&lt;span>提供数据的传送服务。这里涉及到一个信息就是帧，它是数据传输的单元，不同的协议帧的长短也不同。它还有差错恢复，流量控制的功能（这个指的是硬件）&lt;/span>&lt;/p>
&lt;p>&lt;span>&lt;span>ISO1745--1975 、&lt;/span>&lt;span>&lt;span>ISO7776 、&lt;/span>&lt;span>&lt;span>ISO3309--1984&amp;nbsp;&lt;/span>&lt;span>就是这一层的三种不同协议，而每一个协议帧的长短也是不同的。&lt;/span>&lt;/span>&lt;/span>&lt;/span>&lt;/p>
&lt;p>&lt;span>&lt;span>我们常见的链路层产品就是网卡，网桥等。&lt;/span>&lt;/span>&lt;/p>
&lt;p>&lt;span>&lt;span>&lt;span>&lt;br>&lt;/span>&lt;/span>&lt;/span>&lt;/p>
&lt;p>&lt;span>&lt;span>&lt;span>第三层：网络层&amp;nbsp;&lt;/span>&lt;/span>&lt;/span>&lt;/p>
&lt;p>&lt;span>它的作用是路由的选择，网络的激活和终止。它还有的一个重要功能就是在一条数据链路上复用多条网络连接，大多采用的是分时复用的技术。&lt;/span>&lt;/p>
&lt;p>&lt;span>我们常见的是路由器、网关等&lt;/span>&lt;/p>
&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>
&lt;p>&lt;span>第四层：传输层&lt;/span>&lt;/p>
&lt;p>&lt;span>它是两台计算机经过网络进行数据通信时最基础的端到端的一个层次。它的服务满足了传送质量，传达速度，传送费用的不同需要。它还具有差错恢复，流量控制的功能（这个指的是软件）&lt;/span>&lt;/p>
&lt;p>&lt;span>很多时候我们会发现QQ聊天的速度很快，但是我们上网速度就很慢，这就是因为QQ使用UDP协议，没有纠错功能，而网络的传输使用的是TCP协议，它的纠错功能就会导致传输速度变慢。&lt;/span>&lt;/p>
&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>
&lt;p>&lt;span>第五层：会话层&lt;/span>&lt;/p>
&lt;p>&lt;span>它的服务可使应用建立和维持会话。再举个栗子：就像两个人打电话，一个人说，对方听到后回应他，这就是会话层在发挥作用，它能够使信息传递时保持同步，并按次序进行。&lt;/span>&lt;/p>
&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>
&lt;p>&lt;span>第六层：表示层&lt;/span>&lt;/p>
&lt;p>&lt;span>它包括数据的表示形式，文字，图形，图片等都有各自的格式，就像图片的格式有JPG，GIF等。&lt;/span>&lt;/p>
&lt;p>&lt;span>还有就是数据含义，就是数据的符号&lt;/span>&lt;/p>
&lt;p>&lt;span>这一层的作用就是为异种机通信提供一种公共语言，以便相互操作。例如，IBM主机使用EBCDIC编码，而大部分的PC机使用的是ASCII码。这就要表示层来完成这一转换。&lt;/span>&lt;/p>
&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>
&lt;p>&lt;span>第七层：应用层&lt;/span>&lt;/p>
&lt;p>&lt;span>实现应用进程之间的信息交换。同时还有一系列的业务处理所需要的服务功能。像文件的传送，访问和管理，打印服务都是属于应用层。&lt;/span>&lt;/p>
&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>
&lt;p>&lt;span>七层模型是很抽象的一个概念。&lt;/span>&lt;span>一般情况下，&lt;span>物理层，数据链路层，网络层对应的是一个设备，&lt;/span>这个设备在某一层就有某种功能，而&lt;span>传输层，会话层，表示层对应的是协议&lt;/span>，而&lt;span>应用层就是使用什么样的软件&lt;/span>。&lt;/span>&lt;/p></description></item><item><title>大数据行业就业指南</title><link>https://pangyd.com/post/200/</link><pubDate>Mon, 01 Oct 2018 09:00:25 +0800</pubDate><guid>https://pangyd.com/post/200/</guid><description>&lt;p>
&lt;/p>&lt;p align="center">&lt;b>&lt;a name="_Toc518382491">大数据行业就业指南&lt;/a>&lt;/b>&lt;span lang="EN-US">&lt;/span>&lt;/p>
&lt;p>大数据开发工程师&lt;span lang="EN-US">/&lt;/span>大数据运维&lt;span lang="EN-US">/Hadoop&lt;/span>开发：&lt;span lang="EN-US">&lt;/span>&lt;/p>
&lt;p>熟悉&lt;span lang="EN-US">Hadoop&lt;/span>生态圈（
&lt;span lang="EN-US">MapReduce&lt;/span>，&lt;span lang="EN-US">hdfs&lt;/span>，&lt;span lang="EN-US">Hive&lt;/span>，&lt;span lang="EN-US">Spark&lt;/span>等相关组件），&lt;span lang="EN-US">liunx&lt;/span>（&lt;span lang="EN-US">shell&lt;/span>脚本）相关技术以及对源码有深入认识，熟悉&lt;span lang="EN-US">mysql&lt;/span>数据库等，掌握&lt;span lang="EN-US">JAVA&lt;/span>语言或者&lt;span lang="EN-US">python&lt;/span>语言 （有的公司要求掌握&lt;span lang="EN-US">Scala&lt;/span>语言，流式处理框架使用经验，熟悉&lt;span lang="EN-US">Tableau&lt;/span>报表设计&lt;span lang="EN-US">&lt;/span>&lt;/p>
&lt;p>&lt;span lang="EN-US">&amp;nbsp;&lt;/span>&lt;/p>
&lt;p>数据采集工程师&lt;span lang="EN-US">/&lt;/span>网络爬虫工程师&lt;span lang="EN-US">/&lt;/span>反爬虫工程师&lt;span lang="EN-US">:&lt;/span>&lt;/p>
&lt;p>&lt;span lang="EN-US">&lt;span>&amp;nbsp; &lt;/span>&lt;/span>熟悉&lt;span lang="EN-US">Selenium, phantomjs, scrapy&lt;/span>等自动化测试工具，以及爬虫框架，精通&lt;span lang="EN-US">Java/Objective-C/python&lt;/span>等至少一种语言，了解各种前端技术，包括&lt;span lang="EN-US">XHTML/XML/CSS/JavaScript/AJAX&lt;/span>等；熟悉正则表达式和&lt;span lang="EN-US">XPATH&lt;/span>，能够从结构化或非结构化数据中获取信息；熟悉&lt;span lang="EN-US">DDMS&lt;/span>、&lt;span lang="EN-US">Instruments&lt;/span>，&lt;span lang="EN-US">Charles&lt;/span>，&lt;span lang="EN-US">Fildder&lt;/span>等抓包工具&lt;span lang="EN-US">;&lt;/span>，熟悉网络编程，对&lt;span lang="EN-US">TCP/IP&lt;/span>有深入理解，精通&lt;span lang="EN-US">MySQL&lt;/span>或&lt;span lang="EN-US">PostgreSQL&lt;/span>；熟悉&lt;span lang="EN-US">Redis&lt;/span>或&lt;span lang="EN-US">MongoDB&lt;/span>；了解&lt;span lang="EN-US">linux&lt;/span>优先&lt;span lang="EN-US">&lt;/span>&lt;/p>
&lt;p>大数据分析工程师&lt;span lang="EN-US">/&lt;/span>统计建模师&lt;span lang="EN-US">/&lt;/span>数据管理&lt;span lang="EN-US">/&lt;/span>数据统计&lt;span lang="EN-US">&lt;/span>&lt;/p>
&lt;p>&lt;span lang="EN-US">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span>&lt;/span>熟悉&lt;span lang="EN-US">R/Spark/Python&lt;/span>或&lt;span lang="EN-US">C/C++&lt;/span>等至少一个常用语言；以机器学习、深度学习、复杂网络、自然语言处理等其中一种或几种模型见长；对建模技术的前沿探索有热情，优秀的学习能力和逻辑思考能力；对风险管理、用户生命周期管理、或不同垂直领域有深入研究，对各式海量数据分析与挖掘有强烈兴趣。具备&lt;span lang="EN-US">ETL&lt;/span>数据处理能力，有经验者优先，优秀的逻辑思维能力，和数据敏感度，可从海量数据中日趋分析并反推业务逻辑，优化核心业务流程；&lt;span lang="EN-US">&lt;/span>&lt;/p>
&lt;p>数据可视化工程师：&lt;span lang="EN-US">&lt;/span>&lt;/p>
&lt;p>&lt;span lang="EN-US">.&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span>&lt;/span>理解&lt;span lang="EN-US">W3C&lt;/span>标准与&lt;span lang="EN-US">ES&lt;/span>规范，熟悉&lt;span lang="EN-US">Web&lt;/span>语义化，掌握盒模型、常用布局以及浏览器兼容性；熟练掌握各项&lt;span lang="EN-US">Web&lt;/span>前端技术&lt;span lang="EN-US"> (HTML/CSS/Javascript) &lt;/span>，了解&lt;span lang="EN-US">svg&lt;/span>，&lt;span lang="EN-US">canvas&lt;/span>，&lt;span lang="EN-US">webgl&lt;/span>技术；熟练掌握&lt;span lang="EN-US">JET Charts/ECharts/HighCharts/D3.js/Three.js&lt;/span>等图形库熟练使用可视化&lt;span lang="EN-US">BI&lt;/span>工具及前端工具，具有计算机图形学理论基础，熟悉数据可视化相关基础算法；熟悉&lt;span lang="EN-US"> HTTP
&lt;/span>协议及缓存，了解基本的浏览器渲染及网络传输过程，掌握&lt;span lang="EN-US">Java/python&lt;/span>等一门语言，有前端开发经验&lt;span lang="EN-US">/&lt;/span>大规模数据存储，处理经验者优先&lt;span lang="EN-US">&lt;/span>&lt;/p>
&lt;p>&lt;span lang="EN-US">&amp;nbsp;&lt;/span>&lt;/p>&lt;p>&lt;/p></description></item><item><title>Collections 内建集合模块</title><link>https://pangyd.com/post/199-collections/</link><pubDate>Sat, 29 Sep 2018 08:49:45 +0800</pubDate><guid>https://pangyd.com/post/199-collections/</guid><description>&lt;p>
&lt;/p>&lt;p>&lt;span lang="EN-US">Collections &lt;/span>集合类&lt;span lang="EN-US">&lt;/span>&lt;/p>
&lt;h3>&lt;span lang="EN-US">namedtuple&lt;/span>&lt;/h3>
&lt;p>我们知道&lt;code>&lt;span lang="EN-US">tuple&lt;/span>&lt;/code>可以表示不变集合，例如，一个点的二维坐标就可以表示成：&lt;span lang="EN-US">&lt;/span>&lt;/p>
&lt;pre>&lt;span class="prompt">&lt;span lang="EN-US">&amp;gt;&amp;gt;&amp;gt; &lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">p = (&lt;/span>&lt;/code>&lt;span class="number">&lt;span lang="EN-US">1&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">, &lt;/span>&lt;/code>&lt;span class="number">&lt;span lang="EN-US">2&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">)&lt;/span>&lt;/code>&lt;/pre>
&lt;p>但是，看到&lt;code>&lt;span lang="EN-US">(1, 2)&lt;/span>&lt;/code>，很难看出这个&lt;code>&lt;span lang="EN-US">tuple&lt;/span>&lt;/code>是用来表示一个坐标的。&lt;span lang="EN-US">&lt;/span>&lt;/p>
&lt;p>定义一个&lt;span lang="EN-US">class&lt;/span>又小题大做了，这时，&lt;code>&lt;span lang="EN-US">namedtuple&lt;/span>&lt;/code>就派上了用场：&lt;span lang="EN-US">&lt;/span>&lt;/p>
&lt;pre>&lt;span class="prompt">&lt;span lang="EN-US">&amp;gt;&amp;gt;&amp;gt; &lt;/span>&lt;/span>&lt;span class="keyword">&lt;span lang="EN-US">from&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US"> collections &lt;/span>&lt;/code>&lt;span class="keyword">&lt;span lang="EN-US">import&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US"> namedtuple&lt;/span>&lt;/code>&lt;/pre>&lt;pre>&lt;span class="prompt">&lt;span lang="EN-US">&amp;gt;&amp;gt;&amp;gt; &lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">Point = namedtuple(&lt;/span>&lt;/code>&lt;span class="string">&lt;span lang="EN-US">'Point'&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">, [&lt;/span>&lt;/code>&lt;span class="string">&lt;span lang="EN-US">'x'&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">, &lt;/span>&lt;/code>&lt;span class="string">&lt;span lang="EN-US">'y'&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">])&lt;/span>&lt;/code>&lt;/pre>&lt;pre>&lt;span class="prompt">&lt;span lang="EN-US">&amp;gt;&amp;gt;&amp;gt; &lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">p = Point(&lt;/span>&lt;/code>&lt;span class="number">&lt;span lang="EN-US">1&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">, &lt;/span>&lt;/code>&lt;span class="number">&lt;span lang="EN-US">2&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">)&lt;/span>&lt;/code>&lt;/pre>&lt;pre>&lt;span class="prompt">&lt;span lang="EN-US">&amp;gt;&amp;gt;&amp;gt; &lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">p.x&lt;/span>&lt;/code>&lt;/pre>&lt;pre>&lt;span class="number">&lt;span lang="EN-US">1&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">&lt;/span>&lt;/code>&lt;/pre>&lt;pre>&lt;span class="prompt">&lt;span lang="EN-US">&amp;gt;&amp;gt;&amp;gt; &lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">p.y&lt;/span>&lt;/code>&lt;/pre>&lt;pre>&lt;span class="number">&lt;span lang="EN-US">2&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">&lt;/span>&lt;/code>&lt;/pre>
&lt;p>&lt;code>&lt;span lang="EN-US">namedtuple&lt;/span>&lt;/code>是一个函数，它用来创建一个自定义的&lt;code>&lt;span lang="EN-US">tuple&lt;/span>&lt;/code>对象，并且规定了&lt;code>&lt;span lang="EN-US">tuple&lt;/span>&lt;/code>元素的个数，并可以用属性而不是索引来引用&lt;code>&lt;span lang="EN-US">tuple&lt;/span>&lt;/code>的某个元素。&lt;span lang="EN-US">&lt;/span>&lt;/p>
&lt;p>这样一来，我们用&lt;code>&lt;span lang="EN-US">namedtuple&lt;/span>&lt;/code>可以很方便地定义一种数据类型，它具备&lt;span lang="EN-US">tuple&lt;/span>的不变性，又可以根据属性来引用，使用十分方便。&lt;span lang="EN-US">&lt;/span>&lt;/p>
&lt;p>可以验证创建的&lt;code>&lt;span lang="EN-US">Point&lt;/span>&lt;/code>对象是&lt;code>&lt;span lang="EN-US">tuple&lt;/span>&lt;/code>的一种子类：&lt;span lang="EN-US">&lt;/span>&lt;/p>
&lt;pre>&lt;span class="prompt">&lt;span lang="EN-US">&amp;gt;&amp;gt;&amp;gt; &lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">isinstance(p, Point)&lt;/span>&lt;/code>&lt;/pre>&lt;pre>&lt;span class="builtin">&lt;span lang="EN-US">True&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">&lt;/span>&lt;/code>&lt;/pre>&lt;pre>&lt;span class="prompt">&lt;span lang="EN-US">&amp;gt;&amp;gt;&amp;gt; &lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">isinstance(p, tuple)&lt;/span>&lt;/code>&lt;/pre>&lt;pre>&lt;span class="builtin">&lt;span lang="EN-US">True&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">&lt;/span>&lt;/code>&lt;/pre>
&lt;p>类似的，如果要用坐标和半径表示一个圆，也可以用&lt;code>&lt;span lang="EN-US">namedtuple&lt;/span>&lt;/code>定义：&lt;span lang="EN-US">&lt;/span>&lt;/p>
&lt;pre>&lt;span class="comment">&lt;span lang="EN-US"># namedtuple('&lt;/span>名称&lt;span lang="EN-US">', [&lt;/span>属性&lt;span lang="EN-US">list]):&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">&lt;/span>&lt;/code>&lt;/pre>&lt;pre>&lt;span class="constant">&lt;span lang="EN-US">Circle&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US"> = namedtuple(&lt;/span>&lt;/code>&lt;span class="string">&lt;span lang="EN-US">'Circle'&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">, [&lt;/span>&lt;/code>&lt;span class="string">&lt;span lang="EN-US">'x'&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">, &lt;/span>&lt;/code>&lt;span class="string">&lt;span lang="EN-US">'y'&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">, &lt;/span>&lt;/code>&lt;span class="string">&lt;span lang="EN-US">'r'&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">])&lt;/span>&lt;/code>&lt;/pre>
&lt;p>&lt;span lang="EN-US">&amp;nbsp;&lt;/span>&lt;/p>
&lt;p>&lt;b>&lt;span lang="EN-US">Deque&lt;/span>&lt;/b>&lt;span lang="EN-US">&lt;span>&amp;nbsp; &lt;/span>&lt;/span>双向队列&lt;span lang="EN-US">&lt;/span>&lt;/p>
&lt;p>使用&lt;code>&lt;span lang="EN-US">list&lt;/span>&lt;/code>存储数据时，按索引访问元素很快，但是插入和删除元素就很慢了，因为&lt;code>&lt;span lang="EN-US">list&lt;/span>&lt;/code>是线性存储，数据量大的时候，插入和删除效率很低。&lt;span lang="EN-US">&lt;/span>&lt;/p>
&lt;p>&lt;span lang="EN-US">deque&lt;/span>是为了高效实现插入和删除操作的双向列表，适合用于队列和栈：&lt;span lang="EN-US">&lt;/span>&lt;/p>
&lt;p>&lt;span lang="EN-US">list&lt;/span>是线性存储，数据量大的时候，效率慢&lt;span lang="EN-US">&lt;/span>&lt;/p>
&lt;p>&lt;code>&lt;span lang="EN-US">deque&lt;/span>&lt;/code>除了实现&lt;span lang="EN-US">list&lt;/span>的&lt;code>&lt;span lang="EN-US">append()&lt;/span>&lt;/code>和&lt;code>&lt;span lang="EN-US">pop()&lt;/span>&lt;/code>外，还支持&lt;code>&lt;span lang="EN-US">appendleft()&lt;/span>&lt;/code>和&lt;code>&lt;span lang="EN-US">popleft()&lt;/span>&lt;/code>，这样就可以非常高效地往头部添加或删除元素。&lt;span lang="EN-US">&lt;/span>&lt;/p>
&lt;p style="text-align: left" align="left">&lt;b>&lt;span lang="EN-US">defaultdict&lt;/span>&lt;/b>&lt;/p>
&lt;p style="text-align: left" align="left">&lt;span>使用&lt;span lang="EN-US">dict&lt;/span>时，如果引用的&lt;span lang="EN-US">Key&lt;/span>不存在，就会抛出&lt;span lang="EN-US">KeyError&lt;/span>。如果希望&lt;span lang="EN-US">key&lt;/span>不存在时，返回一个默认值，就可以用&lt;span lang="EN-US">defaultdict&lt;/span>：&lt;span lang="EN-US">&lt;/span>&lt;/span>&lt;/p>
&lt;p style="text-align: left" align="left">&lt;span lang="EN-US">&amp;gt;&amp;gt;&amp;gt; from collections import defaultdict&lt;/span>&lt;/p>
&lt;p style="text-align: left" align="left">&lt;span lang="EN-US">&amp;gt;&amp;gt;&amp;gt; dd = defaultdict(lambda: 'N/A')&lt;/span>&lt;/p>
&lt;p style="text-align: left" align="left">&lt;span lang="EN-US">&amp;gt;&amp;gt;&amp;gt; dd['key1'] = 'abc'&lt;/span>&lt;/p>
&lt;p style="text-align: left" align="left">&lt;span lang="EN-US">&amp;gt;&amp;gt;&amp;gt; dd['key1'] # key1&lt;/span>&lt;span>存在&lt;span lang="EN-US">&lt;/span>&lt;/span>&lt;/p></description></item><item><title>训练操作说明</title><link>https://pangyd.com/post/208/</link><pubDate>Thu, 20 Sep 2018 08:28:51 +0800</pubDate><guid>https://pangyd.com/post/208/</guid><description>&lt;p>任务一:以下按顺序启动:&lt;/p>&lt;p>&lt;span>	&lt;/span>zkServer.sh start(三台同时启动);&lt;/p>&lt;p>&lt;span>	&lt;/span>start-dfs.sh （lky01）&lt;/p>&lt;p>&lt;span>	&lt;/span>start-yarn.sh (lky02)&lt;/p>&lt;p>&lt;span>	&lt;/span>yarn-daemon.sh start resourcemanager (lky03)&lt;/p>&lt;p>&lt;span>	&lt;/span>start-spark-all.sh (lky01)&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>任务二:数据采集:&lt;/p>&lt;p>&lt;span>	&lt;/span>在sqoop的bin目录下执行:sqoop import --connect jdbc:mysql://192.168.0.200:3306/retail --username root--password 123456 --table consume_notes --hive-import --create-hive-table -m 1&amp;nbsp; &lt;span>		&lt;/span>(导入成功后，请在hive里删除导入的数据表,以免下次导入出现报错,如出现报错请删除错误日志里面提示的缓存目录:hadoop dfs rm -r [日志错误表位置]).&lt;/p>&lt;p>&lt;span>	&lt;/span>数据预处理&lt;/p>&lt;p>&lt;span>	&lt;/span>在intelij项目里面修改数据库的地址为192.168.0.200,然后打包上传到服务器,在opt/jars/spark/目录下执行./spark-submit.sh [执行类的地址（在intelij拷贝）] 执行完毕后,查看数据库中是否有数&lt;span>		&lt;/span>据 (将执行完毕后出现的数据表进行删除,以免影响下一个人使用).&lt;/p>&lt;p>&lt;span>	&lt;/span>数据挖掘（零售）&lt;/p>&lt;p>&lt;span>	&lt;/span>按照项目代码 创建输入目录,执行项目,在输出文件夹中查看是否有数据.&lt;/p>&lt;p>&lt;span>	&lt;/span>数据挖掘（建筑）&lt;/p>&lt;p>&lt;span>	&lt;/span>在lky01上执行 nc -lk 44445 在本机项目中查看项目配置的ip和端口是否和服务器端配置的一样,确保在同一端口,在JDBC配置的类中修改好输出数据的数据库地址,然后启动本地项目,在服务器界面输入数据，然后查看数据库中是否有刚才输入的数据.&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>任务三:数据可视化:&lt;/p>&lt;p>&lt;span>	&lt;/span>数据源配置:新建数据源;选择jdbc数据源,配置好jdbc的地址,然后保存 (配置数据源的地址为192.168.0.202).&lt;/p>&lt;p>&lt;span>	&lt;/span>数据集配置:新建数据集,按照题目给出的数据查询语句,粘贴到目标框,然后点击读取数据,无误后保存.&lt;/p>&lt;p>&lt;span>	&lt;/span>图表设计:根据题目给出的图表内容 设计图表.&lt;/p></description></item><item><title>程序员相爱相杀鄙视指南</title><link>https://pangyd.com/post/181/</link><pubDate>Sat, 01 Sep 2018 19:00:34 +0800</pubDate><guid>https://pangyd.com/post/181/</guid><description>&lt;p>有人的地方就有江湖。在互联网技术世界里，身为中流砥柱的程序员们，看似每天都坐在屏幕前，两耳不闻公司事，一心苦练编程功。殊不知，在“技术至上”的程序世界，早已暗波汹涌，一条条相爱相杀的鄙视链盘根错节，江湖的争斗久久未分出胜负…&lt;/p>&lt;p>相信吃瓜群众都知道，编程语言是程序员的立身之本，然而，很少有人知道，不同的编程语言出自各派、功能不一，它更代表了程序员在江湖上的地位高低。&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>程序语言太复杂，一旦选不好，就会落入鄙视链的底层！&lt;/p>&lt;p>最心疼的还是 PHP 工程师，明明人家也是为公司奉献很多的，却遭到全体的鄙视。&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>如果你觉得程序员的江湖仅仅只有这些，那你就错了，就拿到底是 Tab 键缩进还是 Space 键缩进来说，就能引起一众程序员争执半天，要知道，理科男一旦认真起来也是很拼的！从九月初沪江发布的《程序员非正式生存指南》来看，多数程序员还是偏爱 Tab 键的。&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>tab 大战空格键，轻松 KO 一边倒&lt;/p>&lt;p>Tab vs Space 的大战刚刚平息，硬件配置的军备赛又将上演。俗话说得好：有纹身的都怕热，用苹果的都没兜。可见硬件配置对于显示地位的重要性，在程序员的世界也不例外，程序员的鄙视链有愈演愈烈之势。&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>面对程序员对设备的执着，老板的心在滴血：养活一个程序员实在是太难了！除了设备的比拼，程序员职场世界的“潜规则”也不少。&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>不敢想象，这群看起来沉迷于“编程世界”里不能自拔的程序员们，连办公环境、座椅舒适度都要比。可怜那些站着写程序的工程师，虽然辛苦，依然没有阻挡其写代码的热情，这股热情，成为其鄙视其他工程师的最大优势。&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>程序猿、设计狮、产品狗之间的相爱相杀也早已成为互联网公司的家常便饭，面对这样的三角鄙视链，只想对广大程序员们道一声：“保重身体，来日再战！”&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>虽然程序员男性居多，但依然有一部分女性冲破阻碍，成为一名光荣的程序媛，在这个男女比例 9:1 的世界里努力奋斗着。既然同为程序员，相互扶持才能共同进步。&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>看了这么多鄙视链，只想问最厉害的程序员到底是谁？！&lt;/p>&lt;p>铛！&lt;/p>&lt;p>铛！&lt;/p></description></item><item><title>Python中操作mysql的pymysql模块详解</title><link>https://pangyd.com/post/197-pythonmysqlpymysql/</link><pubDate>Mon, 06 Aug 2018 18:06:31 +0800</pubDate><guid>https://pangyd.com/post/197-pythonmysqlpymysql/</guid><description>&lt;div>&lt;div>&lt;div class="article">&lt;div data-note-content="" class="show-content">&lt;div class="show-content-free">&lt;p>&lt;a href="https://link.jianshu.com?t=https://github.com/PyMySQL/PyMySQL" target="_blank" rel="nofollow">PyMySQL&lt;/a>是一个Python编写的MySQL驱动程序，让我们可以用Python语言操作MySQL数据库。&lt;/p>
&lt;p>首先，使用pip安装PyMySQL。&lt;/p>
&lt;pre class="hljs undefined">&lt;code>pip install PyMySQL
&lt;/code>&lt;/pre>
&lt;h2>使用PyMySQL&lt;/h2>
&lt;h3>简单使用&lt;/h3>
&lt;p>如果有JDBC等其他语言的数据库学习经验的话，使用PyMySQL非常简单。下面是一个完整的MySQL增删查（没有改）的例子。&lt;/p>
&lt;pre class="hljs python">&lt;code class="python">&lt;span class="hljs-keyword">import&lt;/span> pymysql
&lt;span class="hljs-keyword">import&lt;/span> datetime
&lt;p>host = &lt;span class="hljs-string">&amp;lsquo;localhost&amp;rsquo;&lt;/span>
username = &lt;span class="hljs-string">&amp;lsquo;root&amp;rsquo;&lt;/span>
password = &lt;span class="hljs-string">&amp;lsquo;12345678&amp;rsquo;&lt;/span>
db_name = &lt;span class="hljs-string">&amp;lsquo;test&amp;rsquo;&lt;/span>&lt;/p>
&lt;p>create_table_sql = &lt;span class="hljs-string">&amp;quot;&amp;quot;&amp;quot;&lt;br>
CREATE TABLE fuck(
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(255) UNIQUE ,
nickname VARCHAR(255) NOT NULL ,
birthday DATE
)
&amp;ldquo;&amp;rdquo;&amp;quot;&lt;/span>&lt;/p>
&lt;p>insert_table_sql = &lt;span class="hljs-string">&amp;quot;&amp;quot;&amp;quot;&lt;br>
INSERT INTO fuck(username,nickname,birthday)
VALUES(&amp;rsquo;{username}&amp;rsquo;,&amp;rsquo;{nickname}&amp;rsquo;,&amp;rsquo;{birthday}&amp;rsquo;)
&amp;ldquo;&amp;rdquo;&amp;quot;&lt;/span>&lt;/p>
&lt;p>query_table_sql = &lt;span class="hljs-string">&amp;quot;&amp;quot;&amp;quot;&lt;br>
SELECT id,username,nickname,birthday
FROM fuck
&amp;ldquo;&amp;rdquo;&amp;quot;&lt;/span>&lt;/p>
&lt;p>delete_table_sql = &lt;span class="hljs-string">&amp;quot;&amp;quot;&amp;quot;&lt;br>
DELETE FROM fuck
&amp;ldquo;&amp;rdquo;&amp;quot;&lt;/span>&lt;/p>
&lt;p>drop_table_sql = &lt;span class="hljs-string">&amp;quot;&amp;quot;&amp;quot;&lt;br>
DROP TABLE fuck
&amp;ldquo;&amp;rdquo;&amp;quot;&lt;/span>&lt;/p></description></item><item><title>爬虫分享【1】</title><link>https://pangyd.com/post/196-1/</link><pubDate>Sat, 04 Aug 2018 20:34:47 +0800</pubDate><guid>https://pangyd.com/post/196-1/</guid><description>&lt;p>&lt;/p>&lt;p>
&lt;/p>&lt;p>&lt;span>&lt;span lang="EN-US">Python&lt;/span>&lt;/span>&lt;span>&lt;span>环境：&lt;span lang="EN-US">3.6&lt;/span>&lt;/span>&lt;/span>&lt;span>&lt;span lang="EN-US">&lt;/span>&lt;/span>&lt;/p>
&lt;p>&lt;span>&lt;span>需要的库：&lt;span lang="EN-US">requests &lt;/span>基于&lt;span lang="EN-US">urllib &lt;/span>比&lt;span lang="EN-US">urllib&lt;/span>更加的简洁，&lt;/span>&lt;/span>&lt;span lang="EN-US">BeautifulSoup &lt;/span>&lt;span>：网页解析库&lt;/span>&lt;span>&lt;span lang="EN-US">&lt;/span>&lt;/span>&lt;/p>
&lt;p>&lt;span>&lt;span lang="EN-US">&lt;span>1，&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span>&lt;/span>&lt;/span>&lt;/span>&lt;span>&lt;span lang="EN-US">headers &lt;/span>&lt;/span>&lt;span>&lt;span>头部分 用于向服务器发送信息 伪装成浏览器访问&lt;/span>&lt;/span>&lt;span>&lt;span lang="EN-US">&lt;/span>&lt;/span>&lt;/p>
&lt;p>&lt;span>&lt;span lang="EN-US">&lt;span>2，&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span>&lt;/span>&lt;/span>&lt;/span>&lt;b>&lt;span lang="EN-US">def
&lt;/span>&lt;/b>&lt;span lang="EN-US">save_artist(group_id, initial):&lt;br>
&lt;/span>&lt;span>&lt;span lang="EN-US">params&lt;/span>&lt;/span>&lt;span>&lt;span>：字典，用于组合传递过来的参数&lt;/span>&lt;/span>&lt;span>&lt;span lang="EN-US">&lt;/span>&lt;/span>&lt;/p>
&lt;p>&lt;span lang="EN-US">&lt;span>3，&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span>&lt;/span>&lt;/span>&lt;span lang="EN-US">r&lt;/span>&lt;span>：接收爬虫向服务器发送的参数返回的数据&lt;/span>&lt;span lang="EN-US">&lt;/span>&lt;/p>
&lt;p>&lt;span>&lt;span lang="EN-US">&lt;span>4，&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span>&lt;/span>&lt;/span>&lt;/span>&lt;span>&lt;span lang="EN-US">soup&lt;/span>&lt;/span>&lt;span>&lt;span>：参数有&lt;span lang="EN-US">html&lt;/span>的文档以及设置字符串的编码格式，&lt;span lang="EN-US">htnl&lt;/span>解析器&lt;/span>&lt;/span>&lt;span>&lt;span lang="EN-US">&lt;/span>&lt;/span>&lt;/p>
&lt;p>&lt;span>&lt;span lang="EN-US">&lt;span>5，&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span>&lt;/span>&lt;/span>&lt;/span>&lt;span>&lt;span>获取&lt;span lang="EN-US">soup&lt;/span>的&lt;span lang="EN-US">body&lt;/span>标签，也就是返回的&lt;span lang="EN-US">html&lt;/span>文档的&lt;span lang="EN-US">body &lt;/span>，&lt;span lang="EN-US">attrs&lt;/span>字典参数，如果标签字符中带有&lt;span lang="EN-US">-&lt;/span>以及&lt;span lang="EN-US"> class&lt;/span>不能看作标签属性的时候 用字典参数进行传旨，&lt;span lang="EN-US">artists&lt;/span>和上部分类似&lt;/span>&lt;/span>&lt;span>&lt;span lang="EN-US">&lt;/span>&lt;/span>&lt;/p>
&lt;p>&lt;span>&lt;span lang="EN-US">&lt;span>6，&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span>&lt;/span>&lt;/span>&lt;/span>&lt;span>&lt;span lang="EN-US">For&lt;/span>&lt;/span>&lt;span>&lt;span>循环 将查询到的列表通过遍历进行更深层的数据提取并且转换成格式相对的数据&lt;/span>&lt;/span>&lt;span>&lt;span lang="EN-US">&lt;/span>&lt;/span>&lt;/p>
&lt;p>&lt;span>&lt;span lang="EN-US">&lt;span>7，&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span>&lt;/span>&lt;/span>&lt;/span>&lt;span>&lt;span>然后调用&lt;span lang="EN-US">sql&lt;/span>命令插入到数据库&lt;/span>&lt;/span>&lt;span>&lt;span lang="EN-US">&lt;/span>&lt;/span>&lt;/p>
&lt;p>&lt;span>&lt;span lang="EN-US">&lt;span>8，&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span>&lt;/span>&lt;/span>&lt;/span>&lt;span>&lt;span>函数外面定义爬取网页的参数 &lt;span>&amp;nbsp;&lt;/span>并且定义&lt;span lang="EN-US">for&lt;/span>循环以及&lt;span lang="EN-US">range&lt;/span>函数进行有规律的调用&lt;span lang="EN-US"> sava_artist&lt;/span>进行爬取&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;/p>&lt;pre lay-lang="Python" class="layui-code" skin="notepad">"""
获取所有的歌手信息
"""
import requests
from bs4 import BeautifulSoup
from sql import *
&lt;p>headers = {
&amp;lsquo;Accept&amp;rsquo;: &amp;rsquo;text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,&lt;em>/&lt;/em>;q=0.8&amp;rsquo;,
&amp;lsquo;Accept-Encoding&amp;rsquo;: &amp;lsquo;gzip, deflate, sdch&amp;rsquo;,
&amp;lsquo;Accept-Language&amp;rsquo;: &amp;lsquo;zh-CN,zh;q=0.8,en;q=0.6&amp;rsquo;,
&amp;lsquo;Cache-Control&amp;rsquo;: &amp;rsquo;no-cache&amp;rsquo;,
&amp;lsquo;Connection&amp;rsquo;: &amp;lsquo;keep-alive&amp;rsquo;,
&amp;lsquo;Cookie&amp;rsquo;: &amp;lsquo;_ntes_nnid=7eced19b27ffae35dad3f8f2bf5885cd,1476521011210; _ntes_nuid=7eced19b27ffae35dad3f8f2bf5885cd; usertrack=c+5+hlgB7TgnsAmACnXtAg==; Province=025; City=025; NTES_PASSPORT=6n9ihXhbWKPi8yAqG.i2kETSCRa.ug06Txh8EMrrRsliVQXFV_orx5HffqhQjuGHkNQrLOIRLLotGohL9s10wcYSPiQfI2wiPacKlJ3nYAXgM; &lt;a href="mailto:P_INFO=hourui93@163.com">P_INFO=hourui93@163.com&lt;/a>|1476523293|1|study|11&amp;amp;12|jis&amp;amp;1476511733&amp;amp;mail163#jis&amp;amp;320100#10#0#0|151889&amp;amp;0|g37_client_check&amp;amp;mailsettings&amp;amp;mail163&amp;amp;study&amp;amp;blog|hourui93@163.com; NTES_SESS=Fa2uk.YZsGoj59AgD6tRjTXGaJ8_1_4YvGfXUkS7C1NwtMe.tG1Vzr255TXM6yj2mKqTZzqFtoEKQrgewi9ZK60ylIqq5puaG6QIaNQ7EK5MTcRgHLOhqttDHfaI_vsBzB4bibfamzx1.fhlpqZh_FcnXUYQFw5F5KIBUmGJg7xdasvGf_EgfICWV; S_INFO=1476597594|1|0&amp;amp;80##|hourui93; NETEASE_AUTH_SOURCE=space; NETEASE_AUTH_USERNAME=hourui93; _ga=GA1.2.1405085820.1476521280; JSESSIONID-WYYY=cbd082d2ce2cffbcd5c085d8bf565a95aee3173ddbbb00bfa270950f93f1d8bb4cb55a56a4049fa8c828373f630c78f4a43d6c3d252c4c44f44b098a9434a7d8fc110670a6e1e9af992c78092936b1e19351435ecff76a181993780035547fa5241a5afb96e8c665182d0d5b911663281967d675ff2658015887a94b3ee1575fa1956a5a%3A1476607977016; &lt;em>iuqxldmzr&lt;/em>=25; __utma=94650624.1038096298.1476521011.1476595468.1476606177.8; __utmb=94650624.20.10.1476606177; __utmc=94650624; __utmz=94650624.1476521011.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)&amp;rsquo;,
&amp;lsquo;DNT&amp;rsquo;: &amp;lsquo;1&amp;rsquo;,
&amp;lsquo;Host&amp;rsquo;: &amp;lsquo;music.163.com&amp;rsquo;,
&amp;lsquo;Pragma&amp;rsquo;: &amp;rsquo;no-cache&amp;rsquo;,
&amp;lsquo;Referer&amp;rsquo;: &amp;lsquo;&lt;a href="https://music.163.com/'">https://music.163.com/'&lt;/a>,
&amp;lsquo;Upgrade-Insecure-Requests&amp;rsquo;: &amp;lsquo;1&amp;rsquo;,
&amp;lsquo;User-Agent&amp;rsquo;: &amp;lsquo;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36&amp;rsquo;
}&lt;/p></description></item><item><title>re正则表达式学习</title><link>https://pangyd.com/post/194-re/</link><pubDate>Wed, 01 Aug 2018 14:24:09 +0800</pubDate><guid>https://pangyd.com/post/194-re/</guid><description>&lt;p>&lt;/p>&lt;p>
&lt;/p>&lt;p style="text-align: left" align="left">&lt;span>&lt;span lang="EN-US">&lt;/span>&lt;/span>&lt;span>&lt;span lang="EN-US">Python&lt;/span>&lt;/span>&lt;span>&lt;span>环境：&lt;span lang="EN-US">3.6&lt;/span>&lt;/span>&lt;/span>&lt;span>&lt;span lang="EN-US">&lt;/span>&lt;/span>
&lt;/p>&lt;p style="text-align: left" align="left">&lt;span>&lt;span>需要的库：&lt;span lang="EN-US">re&lt;/span>正则表达式&lt;/span>&lt;/span>&lt;span>&lt;span lang="EN-US">&lt;/span>&lt;/span>&lt;/p>
&lt;p style="text-align: left" align="left">&lt;span>&lt;span>正则表达式的学习&lt;/span>&lt;/span>&lt;span>&lt;span lang="EN-US">&lt;/span>&lt;/span>&lt;/p>
&lt;p style="text-align: left" align="left">&lt;span>&lt;span lang="EN-US">1&lt;/span>&lt;/span>&lt;span>&lt;span>，原子时正则表达式中最基本的组成单位，每个正则表达式至少要包含一个原子，常见的原子有以下几类：&lt;/span>&lt;/span>&lt;span>&lt;span lang="EN-US">&lt;/span>&lt;/span>&lt;/p>
&lt;p style="text-align: left" align="left">&lt;span>&lt;span>普通字符作为原子使用，非打印字符作为原子使用，通用字符作为原子，原子表&lt;/span>&lt;/span>&lt;span>&lt;span lang="EN-US">&lt;/span>&lt;/span>&lt;/p>
&lt;pre>&lt;span>普通字符作为原子：比如数字大小写字符，下划线等 ：&lt;/span>&lt;span>&lt;span lang="EN-US">&lt;/span>&lt;/span>&lt;/pre>&lt;pre>&lt;span lang="EN-US">pattern = &lt;/span>&lt;b>&lt;span lang="EN-US">'yue'&lt;br>
&lt;p>&lt;/span>&lt;/b>&lt;span lang="EN-US">string=&lt;/span>&lt;b>&lt;span lang="EN-US">&amp;lsquo;&lt;a href="https://yum.iqianyue.com">https://yum.iqianyue.com&lt;/a>&amp;rsquo;&lt;br>
&lt;/span>&lt;/b>&lt;span lang="EN-US">result=re.search(pattern,string)&lt;br>
&lt;/span>&lt;span lang="EN-US">print&lt;/span>&lt;span lang="EN-US">(result)&lt;/span>&lt;/pre>&lt;pre>&lt;span>输出：&lt;span lang="EN-US">&amp;lt;_sre.SRE_Match object; span=(16, 19), match=&amp;lsquo;yue&amp;rsquo;&amp;gt;&lt;span>&lt;span>&lt;/span>&lt;/span>&lt;/span>&lt;/span>&lt;/pre>&lt;pre>&lt;span>非打印字符：在字符串中用于格式控制的符号，比如换行符：&lt;/span>&lt;span>&lt;span lang="EN-US">&lt;/span>&lt;/span>&lt;/pre>&lt;pre>&lt;span lang="EN-US">pattern = &lt;/span>&lt;b>&lt;span lang="EN-US">&amp;rsquo;&lt;/span>&lt;/b>&lt;b>&lt;span lang="EN-US">\n&lt;/span>&lt;/b>&lt;b>&lt;span lang="EN-US">&amp;rsquo;&lt;br>
&lt;/span>&lt;/b>&lt;span lang="EN-US">string=&lt;/span>&lt;b>&lt;span lang="EN-US">&amp;lsquo;&amp;lsquo;&amp;lsquo;&lt;a href="https://yum.iqianyue.com">https://yum.iqianyue.com&lt;/a>&lt;br>
&lt;a href="https://baidu.com">https://baidu.com&lt;/a>&lt;br>
&amp;lsquo;&amp;rsquo;&amp;rsquo;&lt;br>
&lt;/span>&lt;/b>&lt;span lang="EN-US">result=re.search(pattern,string)&lt;/span>&lt;/pre>&lt;/p>
&lt;p style="text-align: left" align="left">&lt;span>&lt;span>输出结果：&lt;span lang="EN-US">&amp;lt;_sre.SRE_Match
object; span=(23, 24), match='\n'&amp;gt;&lt;/span>&lt;/span>&lt;/span>&lt;span>&lt;span lang="EN-US">&lt;/span>&lt;/span>&lt;/p>
&lt;p style="text-align: left" align="left">&lt;span>&lt;span>通用字符作为原子：既用一个原子就可以匹配一类字符&lt;/span>&lt;/span>&lt;span>&lt;span lang="EN-US">&lt;/span>&lt;/span>&lt;/p>
&lt;p style="text-align: left" align="left">&lt;span>&lt;span lang="EN-US">\w:&lt;/span>&lt;/span>&lt;span>&lt;span>匹配任意一个字母，数字，下划线&lt;/span>&lt;/span>&lt;span>&lt;span lang="EN-US">&lt;/span>&lt;/span>&lt;/p>
&lt;p style="text-align: left" align="left">&lt;span>&lt;span lang="EN-US">\W:&lt;/span>&lt;/span>&lt;span>&lt;span>匹配除字母，数字，下划线以外的任意一个字符&lt;/span>&lt;/span>&lt;span>&lt;span lang="EN-US">&lt;/span>&lt;/span>&lt;/p>
&lt;p style="text-align: left" align="left">&lt;span>&lt;span lang="EN-US">\d:&lt;/span>&lt;/span>&lt;span>&lt;span>匹配任意一个十进制数&lt;/span>&lt;/span>&lt;span>&lt;span lang="EN-US">&lt;/span>&lt;/span>&lt;/p>
&lt;p style="text-align: left" align="left">&lt;span>&lt;span lang="EN-US">\D:&lt;/span>&lt;/span>&lt;span>&lt;span>匹配除十进制数以外的任意一个其他字符&lt;/span>&lt;/span>&lt;span>&lt;span lang="EN-US">&lt;/span>&lt;/span>&lt;/p>
&lt;p style="text-align: left" align="left">&lt;span>&lt;span lang="EN-US">\s&lt;/span>&lt;/span>&lt;span>&lt;span>：匹配任意一个空白字符&lt;/span>&lt;/span>&lt;span>&lt;span lang="EN-US">&lt;/span>&lt;/span>&lt;/p>
&lt;p style="text-align: left" align="left">&lt;span>&lt;span lang="EN-US">\S:&lt;/span>&lt;/span>&lt;span>&lt;span>匹配除空白字符外的任意一个其他字符&lt;/span>&lt;/span>&lt;span>&lt;span lang="EN-US">&lt;/span>&lt;/span>&lt;/p>
&lt;p style="text-align: left" align="left">&lt;span>&lt;span lang="EN-US">Python %&lt;/span>&lt;/span>&lt;span>&lt;span>操作符&lt;/span>&lt;/span>&lt;span>&lt;span lang="EN-US">&lt;/span>&lt;/span>&lt;/p>
&lt;p style="text-align: left" align="left">&lt;b>&lt;span lang="EN-US">%s &lt;/span>&lt;/b>&lt;span>字符串&lt;span lang="EN-US"> (&lt;/span>采用&lt;span lang="EN-US">str()&lt;/span>的显示&lt;span lang="EN-US">)&lt;/span>&lt;/span>&lt;/p>
&lt;p style="text-align: left" align="left">&lt;b>&lt;span lang="EN-US">%r &lt;/span>&lt;/b>&lt;span>字符串&lt;span lang="EN-US"> (&lt;/span>采用&lt;span lang="EN-US">repr()&lt;/span>的显示&lt;span lang="EN-US">)&lt;/span>&lt;/span>&lt;/p>
&lt;p style="text-align: left" align="left">&lt;b>&lt;span lang="EN-US">%c&lt;/span>&lt;/b>&lt;span lang="EN-US"> &lt;/span>&lt;span>单个字符&lt;span lang="EN-US">&lt;/span>&lt;/span>&lt;/p>
&lt;p style="text-align: left" align="left">&lt;b>&lt;span lang="EN-US">%d&lt;/span>&lt;/b>&lt;span lang="EN-US"> &lt;/span>&lt;span>十进制整数&lt;span lang="EN-US">&lt;/span>&lt;/span>&lt;/p>
&lt;p style="text-align: left" align="left">&lt;b>&lt;span lang="EN-US">%i &lt;/span>&lt;/b>&lt;span>十进制整数&lt;span lang="EN-US">&lt;/span>&lt;/span>&lt;/p>
&lt;p style="text-align: left" align="left">&lt;b>&lt;span lang="EN-US">%f&lt;/span>&lt;/b>&lt;span lang="EN-US"> &lt;/span>&lt;span>浮点数&lt;span lang="EN-US">&lt;/span>&lt;/span>&lt;/p>
&lt;p style="text-align: left" align="left">&lt;b>&lt;span lang="EN-US">%F&lt;/span>&lt;/b>&lt;span lang="EN-US"> &lt;/span>&lt;span>浮点数，与上相同&lt;span lang="EN-US">%% &lt;/span>字符&lt;span lang="EN-US">"%"&lt;/span>&lt;/span>&lt;/p>
&lt;pre>&lt;span lang="EN-US">pattern = &lt;/span>&lt;b>&lt;span lang="EN-US">'\wpython\w'&lt;br>
&lt;/span>&lt;/b>&lt;span lang="EN-US">string=&lt;/span>&lt;b>&lt;span lang="EN-US">'abcdfphp3145pythony_py'&lt;br>
&lt;/span>&lt;/b>&lt;span lang="EN-US">result=re.search(pattern,string)&lt;/span>&lt;/pre>
&lt;p style="text-align: left" align="left">&lt;span>输出：&lt;span lang="EN-US">&amp;lt;_sre.SRE_Match object; span=(11, 19), match='5pythony'&amp;gt;&lt;/span>&lt;/span>&lt;/p>
&lt;p style="text-align: left" align="left">&lt;span>&lt;span>原子表：原子表用&lt;span lang="EN-US">[ ]&lt;/span>表示，匹配时会取该原子表中的任意一个原子进行匹配&lt;/span>&lt;/span>&lt;span>&lt;span lang="EN-US">&lt;/span>&lt;/span>&lt;/p>
&lt;p style="text-align: left" align="left">&lt;span>&lt;span lang="EN-US">[abc]:&lt;/span>&lt;/span>&lt;span>&lt;span>表示之匹配&lt;span lang="EN-US">a&lt;/span>或者&lt;span lang="EN-US">b&lt;/span>或者&lt;span lang="EN-US">c&lt;/span>，&lt;span lang="EN-US">abc&lt;/span>这三个原子之间地位平等&lt;/span>&lt;/span>&lt;span>&lt;span lang="EN-US">&lt;/span>&lt;/span>&lt;/p>
&lt;p style="text-align: left" align="left">&lt;span>&lt;span lang="EN-US">[^]&lt;/span>&lt;/span>&lt;span>&lt;span>代表除了中括号里面的原子均能进行匹配：例如&lt;span lang="EN-US">[^xyz]py&lt;/span>能匹配&lt;span lang="EN-US">apy &lt;/span>但是却不能匹配&lt;span lang="EN-US">xpy&lt;/span>&lt;/span>&lt;/span>&lt;span>&lt;span lang="EN-US">&lt;/span>&lt;/span>&lt;/p>
&lt;p style="text-align: left" align="left">&lt;span>&lt;span lang="EN-US">2&lt;/span>&lt;/span>&lt;span>&lt;span>，元字符&lt;/span>&lt;/span>&lt;span>&lt;span lang="EN-US">&lt;/span>&lt;/span>&lt;/p>
&lt;p style="text-align: left" align="left">&lt;span>&lt;span>元字符就是正则表达式中具有特殊含义的字符，比如重复&lt;span lang="EN-US">N&lt;/span>次前面的字符等&lt;/span>&lt;/span>&lt;span>&lt;span lang="EN-US">&lt;/span>&lt;/span>&lt;/p></description></item><item><title>Python基础</title><link>https://pangyd.com/post/195-python/</link><pubDate>Tue, 31 Jul 2018 20:32:54 +0800</pubDate><guid>https://pangyd.com/post/195-python/</guid><description>&lt;p>&lt;/p>&lt;p>&lt;span>&lt;span lang="EN-US">Try&lt;/span>&lt;/span>&lt;span>&lt;span>：&lt;span lang="EN-US">except&lt;/span>：&lt;span lang="EN-US">exception&lt;/span>&lt;/span>&lt;/span>&lt;span>&lt;span lang="EN-US">&lt;/span>&lt;/span>
&lt;/p>&lt;p style="text-align: left" align="left">&lt;span>&lt;span lang="EN-US">Split&lt;/span>&lt;/span>&lt;span>&lt;span>（）切片函数的使用：&lt;/span>&lt;/span>&lt;span>&lt;span lang="EN-US">&lt;/span>&lt;/span>&lt;/p>
&lt;p style="text-align: left" align="left">&lt;span lang="EN-US">str.split(str="", num=string.count(str)).&lt;/span>&lt;span>&lt;span lang="EN-US">&lt;/span>&lt;/span>&lt;/p>
&lt;p style="text-align: left" align="left">&lt;span>&lt;span lang="EN-US">Split()&lt;/span>&lt;/span>&lt;span>&lt;span>函数内有两个参数 一个是分割符，默认为换行符，制表位，空格，空字符，另一个是分割的次数返回分割后的字符串列表&lt;/span>&lt;/span>&lt;span>&lt;span lang="EN-US">&lt;/span>&lt;/span>&lt;/p>
&lt;p style="text-align: left" align="left">&lt;span lang="EN-US">a='Beautiful, is; better*than\nugly'&lt;/span>&lt;/p>
&lt;p style="text-align: left" align="left">&lt;span lang="EN-US"># &lt;/span>&lt;span>四个分隔符为：&lt;span lang="EN-US">,&lt;span>&amp;nbsp; &lt;/span>;&lt;span>&amp;nbsp;
&lt;/span>*&lt;span>&amp;nbsp; &lt;/span>\n&lt;/span>&lt;/span>&lt;/p>
&lt;p style="text-align: left" align="left">&lt;span lang="EN-US">x= re.split(',|; |\*|\n',a)&lt;/span>&lt;/p>
&lt;p style="text-align: left" align="left">&lt;span lang="EN-US">print(x)&lt;/span>&lt;/p>
&lt;p style="text-align: left" align="left">&lt;span>&lt;span>利用&lt;span lang="EN-US">re&lt;/span>切割含有多种分割符的字符串&lt;/span>&lt;/span>&lt;span>&lt;span lang="EN-US">&lt;/span>&lt;/span>&lt;/p>
&lt;p>&lt;/p></description></item><item><title>如何从命令提示符运行Java程序</title><link>https://pangyd.com/post/193-java/</link><pubDate>Sat, 28 Jul 2018 13:51:21 +0800</pubDate><guid>https://pangyd.com/post/193-java/</guid><description>&lt;div class="left" data-reactid=".0.1.0">&lt;div data-reactid=".0.1.0.0">&lt;div class="post" data-reactid=".0.1.0.0.0">&lt;div class="post-main clearfix" data-reactid=".0.1.0.0.0.1">&lt;div class="content-wrapper" id="post_content_wrapper" data-reactid=".0.1.0.0.0.1.1">&lt;div class="content rich" data-reactid=".0.1.0.0.0.1.1.1">&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>Java是最常用的编程语言之一。 它也是一个IDE密集型编程语言，与Eclipse紧密集成。 如果您刚开始学习Java，下面是帮助您从命令提示符开始运行Java应用程序（在Windows中）的基本指南。&lt;/p>&lt;p>&lt;span>安装Java开发工具包（JDK）&lt;/span>&lt;/p>&lt;p>在您的计算机上运行Java程序之前，您需要安装一个Java编译器。它附带了Java开发工具包或JDK。它是Java在任何平台上开发的基本工具。JDK与Java运行时环境(或JRE)不一样，如果您在您的机器上使用过Java应用程序，您已经安装了它。&lt;/p>&lt;p>1．从Oracle的网站上下载JDK。确保不要下载到服务器版本的JRE。&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>2．确保您获取了开发工具包的Windows版本。&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>3.正常运行安装程序。&lt;/p>&lt;p>&lt;span>从命令提示符运行Java程序&lt;/span>&lt;/p>&lt;p>1.使用记事本或其他文本编辑器创建一个如下所示的简单Java程序。 请确保以扩展名“.java”而不是“.txt”保存文件。&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>2.从开始菜单打开命令提示符。 您也可以按Win R，然后在运行字段中输入cmd.exe。&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>3.使用cd命令将工作目录更改为包含Java程序的目录。 我保存在我的“脚本”文件夹中，但是您可以将您的文件保存在系统中的任何位置。&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>4．在您的计算机上定位到Java开发工具包(JDK)版本的路径。如果你运行64位Windows，那通常是在“C：\ Program Files \ Java”中。&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>5.使用“set”命令设置JDK的路径，如下所示：&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>您可能需要更改目录路径以反映当前版本的Java。确保您使用的是Java开发工具包(JDK)目录，并指向“bin”文件夹。Java运行时环境(JRE)文件夹也包含一个“bin”文件夹，但不包含Java编译器。如果在编译过程中出现错误，请确保使用正确的目录路径。&lt;/p>&lt;p>6.使用javac命令编译Java程序，如下所示：&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>7.你应该看到什么都没有发生。 但是，如果您使用dir命令，则会在您的目录中以“.class”扩展名结尾注意到一个新文件。 这表示程序已经编译完成。&lt;/p></description></item><item><title>关联分析规则</title><link>https://pangyd.com/post/198/</link><pubDate>Tue, 10 Jul 2018 10:30:25 +0800</pubDate><guid>https://pangyd.com/post/198/</guid><description>&lt;p>&lt;span>&lt;span>&lt;span>&lt;strong>关联规则是指从大量数据中挖掘出有价值的数据项之间的相关关系，用关联规则表示出来，从而为当前市场经济发展提供准确的决策手段。&lt;/strong>&lt;/span>&lt;/span>&lt;/span>&lt;/p>
&lt;p>&lt;span>&lt;span>&lt;strong>关联规则中三个重要的衡量指标：&lt;/strong>&lt;/span>&lt;/span>&lt;/p>&lt;span>&lt;span>
&lt;p>&lt;span>（&lt;span lang="EN-US">1&lt;/span>）支持度（&lt;span lang="EN-US">support&lt;/span>）&lt;span lang="EN-US">&lt;/span>&lt;/span>&lt;/p>
&lt;p>&lt;span>支持度是指在所有项目集中&lt;span lang="EN-US">{X, 
Y}&lt;/span>出现的可能性，即项目集中同时含有&lt;span lang="EN-US">X&lt;/span>和&lt;span lang="EN-US">Y&lt;/span>的概率，记为&lt;/span>&lt;span lang="EN-US">&lt;/span>&lt;span>；&lt;/span>&lt;/p>
&lt;p>&lt;span>（&lt;span lang="EN-US">2&lt;/span>）置信度（&lt;span lang="EN-US">confidence&lt;/span>）&lt;span lang="EN-US">&lt;/span>&lt;/span>&lt;/p>
&lt;p>&lt;span>置信度表示在先决条件&lt;span lang="EN-US">X&lt;/span>发生的条件下，关联结果&lt;span lang="EN-US">Y&lt;/span>发生的概率&lt;span lang="EN-US">,&lt;/span>记为&lt;span>；&lt;/span>&lt;/span>&lt;span lang="EN-US">&lt;/span>&lt;span lang="EN-US">&lt;/span>&lt;/p>
&lt;p>&lt;span>（&lt;span lang="EN-US">3&lt;/span>）提升度（&lt;span lang="EN-US">lift&lt;/span>）&lt;/span>&lt;/p>
&lt;p>&lt;span>&lt;/span>&lt;span>提升度表示在含有&lt;span lang="EN-US">X&lt;/span>的条件下同时含有&lt;span lang="EN-US">Y&lt;/span>的可能性与没有&lt;span lang="EN-US">X&lt;/span>这个条件下项目集中含有&lt;span lang="EN-US">Y&lt;/span>的可能性之比，记为&lt;/span>&lt;span lang="EN-US">&lt;/span>&lt;span>。&lt;/span>&lt;/p>
&lt;p>&lt;span>&lt;/span>&amp;nbsp;&lt;/p>&lt;/span>&lt;/span>
&lt;p>&lt;span>&lt;span>&lt;strong>关联规则挖掘&lt;/strong>&lt;strong>总体过程主要包括两步：&lt;/strong>&lt;/span>&lt;/span>&lt;/p>
&lt;p>&lt;span>&lt;span>&lt;strong>&amp;nbsp;&amp;nbsp; &lt;/strong>&lt;/span>&lt;/span>&lt;span lang="EN-US">&lt;span>（1）&lt;/span>&lt;/span>&lt;span>找出所有支持度≥最小支持度的频繁项目集；&lt;/span>&lt;/p>
&lt;p>&lt;span>&amp;nbsp;&amp;nbsp; &lt;/span>&lt;span lang="EN-US">&lt;span>（2）&lt;/span>&lt;/span>&lt;span>由频繁项目集生成满足≥最小置信度的关联规则。&lt;/span>&lt;/p>
&lt;p>&lt;span>&lt;strong>构造Apriori算法模型：&lt;/strong>&lt;/span>&lt;/p>
&lt;p>&lt;span>关联规则挖掘算法中最经典的是&lt;span lang="EN-US">Apriori&lt;/span>算法，它利用逐层搜索的迭代方法来完成频繁项集的挖掘，即利用&lt;/span>&lt;span lang="EN-US">(&lt;i>k&lt;/i>-1)-&lt;/span>&lt;span>项集产生&lt;/span>&lt;i>&lt;span lang="EN-US">k&lt;/span>&lt;/i>&lt;span lang="EN-US">-&lt;/span>&lt;span>项集。具体做法如下：&lt;/span>&lt;span lang="EN-US">&lt;/span>&lt;/p>
&lt;p>&lt;span lang="EN-US">&lt;span>（1）&lt;/span>&lt;/span>&lt;span>找出所有的频繁&lt;/span>&lt;span lang="EN-US">1-&lt;/span>&lt;span>项集，记为&lt;/span>&lt;span lang="EN-US">&lt;/span>&lt;span>；&lt;/span>&lt;span lang="EN-US">&lt;/span>&lt;/p>
&lt;p>&lt;span lang="EN-US">&lt;span>（2）&lt;/span>&lt;/span>&lt;span>利用&lt;/span>&lt;span lang="EN-US">&lt;/span>&lt;span>来挖掘频繁&lt;/span>&lt;span lang="EN-US">2-&lt;/span>&lt;span>项集&lt;/span>&lt;span lang="EN-US">&lt;/span>&lt;span>，如此不断循环，直至找到所有的频繁&lt;/span>&lt;i>&lt;span lang="EN-US">k&lt;/span>&lt;/i>&lt;span lang="EN-US">-&lt;/span>&lt;span>项集为止；&lt;/span>&lt;span lang="EN-US">&lt;/span>&lt;/p>
&lt;p>&lt;span lang="EN-US">&lt;span>（3）&lt;/span>&lt;/span>&lt;span>计算每类中各个规则的支持度，找出所有支持度≥最小支持度的规则&lt;/span>&lt;span>即为关联规则。&lt;/span>&lt;span lang="EN-US">&lt;/span>&lt;/p></description></item><item><title>未来Kotlin取代Java或成为可能</title><link>https://pangyd.com/post/189-kotlinjava/</link><pubDate>Sat, 30 Jun 2018 21:04:58 +0800</pubDate><guid>https://pangyd.com/post/189-kotlinjava/</guid><description>&lt;p>未来Kotlin取代Java或成为可能&amp;nbsp;&lt;/p>&lt;p>Java遇上大麻烦了!一种新的编程语言Kotlin或将取代Java成为Android开发中的主要语言。不过对于外行人来说，Kotlin是什么鬼?Kotlin真的会取代Java吗?今天小编就来说说关于Kotlin的那些事。&amp;nbsp;&lt;/p>&lt;p>&amp;nbsp;&lt;/p>&lt;p>Kotlin取代Java是真的吗?&amp;nbsp;&lt;/p>&lt;p>Kotlin 是一个基于 JVM 的新的编程语言，由 JetBrains 开发。Kotlin可以编译成Java字节码，也可以编译成JavaScript，方便在没有JVM的设备上运行。目前Kotlin已正式成为Android官方开发语言，未来Kotlin取代Java还是有希望的。&amp;nbsp;&lt;/p>&lt;p>随着Kotlin的诞生及应用，市场上流传着Kotlin取代Java成为Android开发的主要语言。以下是小编整理的Kotlin的优点及不足：&amp;nbsp;&lt;/p>&lt;p>Kotlin的优点：&amp;nbsp;&lt;/p>&lt;p>对于 Android 开发者而言，Kotlin 有很多优点。Kotlin 完全兼容现有的 Java 工具和函数库，同时能够很好的在 Android Studio 中使用。最明显的是它的类型系统和对空类型的处理，Kotlin 有助于公平的竞争环境。&amp;nbsp;&lt;/p>&lt;p>Kotlin 迈出了 Android 开发的一大步，从一个开发者的经验来看，Kotlin 是 Android 应用开发的未来。对于初学者来说，Kotlin 很简洁，它具备其他现代语言的特性，它由 JetBrains 这样很专业的团队进行持续的开发，同时一直有社区的支持，因为它是开源的!因此可见，未来Kotlin取代Java其实是有迹可循的。&amp;nbsp;&lt;/p>&lt;p>Kotlin的不足：&amp;nbsp;&lt;/p>&lt;p>Kotlin缺乏成熟的模式和广泛的实践，这样就造成了使用Kotlin编写的代码很难得到维护。另一方面来说，如果项目规模较大将很难引入 Kotlin，因为Kotlin 存在的主要问题：静态代码分析工具的缺乏和成熟设计模式的缺乏。从 Kotlin 缺乏静态代码分析工具可以看出来。&amp;nbsp;&lt;/p>&lt;p>虽然 Java 的静态代码分析工具不完美，但它们可以作为衡量技术债务的好指标。Java 工具不能用于 Kotlin，因为它们专门分析的是 Java 语言源码。综合来看，Kotlin取代Java的路还很长。&amp;nbsp;&lt;/p>&lt;p>当前Kotlin的应用已经令很多学习Java的人内心产生动摇，不过从技术面来说，Java的应用并不仅限于Android开发，目前Java被广泛应用于企业级网站开发、游戏开发等方面&lt;/p></description></item><item><title>程序员的日常</title><link>https://pangyd.com/post/190/</link><pubDate>Tue, 26 Jun 2018 11:31:21 +0800</pubDate><guid>https://pangyd.com/post/190/</guid><description>&lt;p>&lt;span>大神写的代码&lt;/span>&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>&lt;span>自己写的代码&lt;/span>&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p></description></item><item><title>JavaScript容错的优雅地降级功能</title><link>https://pangyd.com/post/191-javascript/</link><pubDate>Mon, 25 Jun 2018 19:32:47 +0800</pubDate><guid>https://pangyd.com/post/191-javascript/</guid><description>&lt;p>探测到错误时禁用组件是一回事。处理出错的组件并将其从UI中优雅地移除是另一回事。即使我们努力保持组件之间松耦合，但涉及到DOM时，这项工作会变得很有难度。例如，我们是否真的可以在不影响周边元素的情况下移除出错组件的DOM元素呢，或者这样做是否会更好——将元素保留在原处，只是将它们隐藏并禁用所有的JavaScript处理函数？&lt;/p>&lt;p>我们采取的实现方式取决于我们在构建什么，即应用的本质。有的应用采用合理的方式组合组件和布局页面，使得添加和移除功能甚为方便。不要以为视觉设计只是一块可以从系统中随意拆除的皮肤，不会带来任何后果。理论上说，它应该独立于系统的其他部分，但实际上，这种思想是不可行的。页面元素的布局对扩展是有影响的，例如，当组件出错时，我们是否能够在不影响系统其他部分的情况下，将他们禁用或修复。&lt;/p>&lt;p>我们可将处理出错组件的过程比喻成关机，因为这通常涉及一系列的操作——以便优雅降级。功能很少整体失效，通常是某个组件失效，导致功能不正常。例如，路由器出错并导致某个功能失效。此时，除了关闭失效的路由处理器，我们还需要关闭该功能涉及的一系列其他组件，将它们从UI中移除，并提示错误信息。我们应为任何功能考虑和测试这种关机流程。我们要保护的不是功能本身，而是移除功能后系统的剩余部分。&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p></description></item><item><title>Kotlin 扩展函数详解与应用</title><link>https://pangyd.com/post/185-kotlin/</link><pubDate>Fri, 23 Feb 2018 11:31:21 +0800</pubDate><guid>https://pangyd.com/post/185-kotlin/</guid><description>&lt;h1 id="一什么是扩展函数">&lt;a href="https://www.jianshu.com/u/dcf7bd45aecd" target="_blank">一、什么是扩展函数？&lt;/a>&lt;/h1>&lt;p>扩展函数数是指在一个类上增加一种新的行为，甚至我们没有这个类代码的访问权限。这是一个在缺少有用函数的类上扩展的方法，Kotlin能够为我们做到那些令人关注的事情，而这些Java做不到。&lt;/p>&lt;p>在Java中，通常会实现很多带有static方法的工具类，而Kotlin中扩展函数的一个优势是我们不需要在调用方法的时候把整个对象当作参数传入，它表现得就像是属于这个类的一样，而且我们可以使用this关键字和调用所有public方法。&lt;/p>&lt;h1 id="二扩展函数的使用">&lt;a name="t1">&lt;/a>&lt;a href="https://www.jianshu.com/u/dcf7bd45aecd" target="_blank">二、扩展函数的使用&lt;/a>&lt;/h1>&lt;h3 id="1函数的扩展">&lt;a name="t2">&lt;/a>（1）函数的扩展&lt;/h3>&lt;p>简单来说，Kotlin扩展函数允许我们在不改变已有类的情况下，为类添加新的函数。例如，我们能够为Activity中添加新的方法，让我们以更简单术语显示toast，并且这个函数不需要传入任何context，它可以被任何Context或者它的子类调用，比如Activity或者Service：&lt;/p>&lt;pre class="prettyprint">&lt;code class="hljs avrasm has-numbering">fun Context&lt;span class="hljs-preprocessor">.toast&lt;/span>(message: CharSequence, duration: Int = Toast&lt;span class="hljs-preprocessor">.LENGTH&lt;/span>_SHORT) {
 Toast&lt;span class="hljs-preprocessor">.makeText&lt;/span>(this, message, duration)&lt;span class="hljs-preprocessor">.show&lt;/span>()
}&lt;/code>&lt;ul class="pre-numbering" style="text-align: right">&lt;li>1&lt;/li>&lt;li>2&lt;/li>&lt;li>3&lt;/li>&lt;/ul>&lt;/pre>&lt;p>当然你也可以这样写：&lt;/p>&lt;pre class="prettyprint">&lt;code class="hljs avrasm has-numbering">fun Activity&lt;span class="hljs-preprocessor">.toast&lt;/span>(message: CharSequence, duration: Int = Toast&lt;span class="hljs-preprocessor">.LENGTH&lt;/span>_SHORT){
 Toast&lt;span class="hljs-preprocessor">.makeText&lt;/span>(this, message, duration)&lt;span class="hljs-preprocessor">.show&lt;/span>()
}&lt;/code>&lt;ul class="pre-numbering" style="text-align: right">&lt;li>1&lt;/li>&lt;li>2&lt;/li>&lt;li>3&lt;/li>&lt;/ul>&lt;/pre>&lt;p>对参数的解释：&amp;nbsp;&lt;br>- Activity：表示函数的接收者，也就是函数扩展的对象&amp;nbsp;&lt;br>- . ：扩展函数修饰符&amp;nbsp;&lt;br>- toast：扩展函数的名称&lt;/p>&lt;p>我们可以在任何地方（例如在一个工具类文件中）声明这个函数，然后在我们的Activity中将它作为普通方法来直接使用（这里的两种使用方式后文会做解释）：&lt;/p>&lt;pre class="prettyprint">&lt;code class="hljs scss has-numbering">override fun &lt;span class="hljs-function">onCreate(savedInstanceState: Bundle?)&lt;/span> { 
 &lt;span class="hljs-value">super&lt;/span>&amp;lt;BaseActivity&amp;gt;&lt;span class="hljs-class">.onCreate&lt;/span>(savedInstanceState)
 &lt;span class="hljs-function">toast(&lt;span class="hljs-string">"This is onCreate!!"&lt;/span>)&lt;/span>
 &lt;span class="hljs-function">toast(&lt;span class="hljs-string">"Hello world!"&lt;/span>, Toast.LENGTH_LONG)&lt;/span>
}&lt;/code>&lt;ul class="pre-numbering" style="text-align: right">&lt;li>1&lt;/li>&lt;li>2&lt;/li>&lt;li>3&lt;/li>&lt;li>4&lt;/li>&lt;li>5&lt;/li>&lt;/ul>&lt;/pre>&lt;p>当然了，Anko已经包括了自己的toast扩展函数，跟上面这个很相似（关于Anko是什么，你可以看我的这篇文章。。。）。Anko提供了一些针对CharSequence和resource的函数，还有两个不同的toast和longToast方法：&lt;/p>&lt;pre class="prettyprint">&lt;code class="hljs erlang has-numbering">&lt;span class="hljs-function">&lt;span class="hljs-title">toast&lt;/span>&lt;span class="hljs-params">(&lt;span class="hljs-string">"Hello world!"&lt;/span>)&lt;/span>
&lt;span class="hljs-title">longToast&lt;/span>&lt;span class="hljs-params">(&lt;span class="hljs-variable">R&lt;/span>.id.hello_world)&lt;/span>&lt;/span>&lt;/code>&lt;ul class="pre-numbering" style="text-align: right">&lt;li>1&lt;/li>&lt;li>2&lt;/li>&lt;/ul>&lt;/pre>&lt;p>&lt;strong>有一点值得注意：&lt;/strong>扩展函数并不是真正地修改了原来的类，它的这些作用效果是以静态导入的方式来实现的。扩展函数可以被声明在任何文件中，因此有个通用的方式是把一系列有关的函数放在一个新建的文件里，就像我们刚才所说的工具类当中。&lt;/p>&lt;p>我觉得还是再举几个几个例子来说明一下吧，因为它们完全显示扩展函数的力量。&lt;/p>&lt;h5 id="在-toast-中的高级用法">● 在 Toast 中的高级用法&lt;/h5>&lt;p>我们首先看看这个例子：&lt;/p>&lt;pre class="prettyprint">&lt;code class="hljs avrasm has-numbering">fun Context&lt;span class="hljs-preprocessor">.niceToast&lt;/span>(message: String,
 tag: String = javaClass&amp;lt;MainActivity&amp;gt;()&lt;span class="hljs-preprocessor">.getSimpleName&lt;/span>(),
 length: Int = Toast&lt;span class="hljs-preprocessor">.LENGTH&lt;/span>_SHORT) {
 Toast&lt;span class="hljs-preprocessor">.makeText&lt;/span>(this, &lt;span class="hljs-string">"[$className] $message"&lt;/span>, length)&lt;span class="hljs-preprocessor">.show&lt;/span>()
}&lt;/code>&lt;ul class="pre-numbering" style="text-align: right">&lt;li>1&lt;/li>&lt;li>2&lt;/li>&lt;li>3&lt;/li>&lt;li>4&lt;/li>&lt;li>5&lt;/li>&lt;/ul>&lt;/pre>&lt;p>我们增加了一个默认值是类名的参数，如果这是在Java中的话，那么总数开销会以几何形式增长，而现在我们可以通过以下方式调用：&lt;/p></description></item><item><title>聊聊分布式事务，再说说解决方案</title><link>https://pangyd.com/post/145/</link><pubDate>Tue, 09 Jan 2018 11:31:21 +0800</pubDate><guid>https://pangyd.com/post/145/</guid><description>&lt;p>&lt;br>&lt;/p>&lt;h3>前言&lt;/h3>&lt;p>&lt;br>&lt;/p>&lt;p>分布式事务是企业集成中的一个技术难点，也是每一个分布式系统架构中都会涉及到的一个东西，特别是在微服务架构中，几乎可以说是无法避免，本文就分布式事务来简单聊一下。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;h3>数据库事务&lt;/h3>&lt;p>&lt;br>&lt;/p>&lt;p>在说分布式事务之前，我们先从数据库事务说起。 数据库事务可能大家都很熟悉，在开发过程中也会经常使用到。但是即使如此，可能对于一些细节问题，很多人仍然不清楚。比如很多人都知道数据库事务的几个特性：原子性(Atomicity )、一致性( Consistency )、隔离性或独立性( Isolation)和持久性(Durabilily)，简称就是ACID。但是再往下比如问到隔离性指的是什么的时候可能就不知道了，或者是知道隔离性是什么但是再问到数据库实现隔离的都有哪些级别，或者是每个级别他们有什么区别的时候可能就不知道了。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>本文并不打算介绍这些数据库事务的这些东西，有兴趣可以搜索一下相关资料。不过有一个知识点我们需要了解，就是假如数据库在提交事务的时候突然断电，那么它是怎么样恢复的呢？ 为什么要提到这个知识点呢？ 因为分布式系统的核心就是处理各种异常情况，这也是分布式系统复杂的地方，因为分布式的网络环境很复杂，这种“断电”故障要比单机多很多，所以我们在做分布式系统的时候，最先考虑的就是这种情况。这些异常可能有 机器宕机、网络异常、消息丢失、消息乱序、数据错误、不可靠的TCP、存储数据丢失、其他异常等等…&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>我们接着说本地事务数据库断电的这种情况，它是怎么保证数据一致性的呢？我们使用SQL Server来举例，我们知道我们在使用 SQL Server 数据库是由两个文件组成的，一个数据库文件和一个日志文件，通常情况下，日志文件都要比数据库文件大很多。数据库进行任何写入操作的时候都是要先写日志的，同样的道理，我们在执行事务的时候数据库首先会记录下这个事务的redo操作日志，然后才开始真正操作数据库，在操作之前首先会把日志文件写入磁盘，那么当突然断电的时候，即使操作没有完成，在重新启动数据库时候，数据库会根据当前数据的情况进行undo回滚或者是redo前滚，这样就保证了数据的强一致性。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>接着，我们就说一下分布式事务。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;h3>分布式理论&lt;/h3>&lt;p>&lt;br>&lt;/p>&lt;p>当我们的单个数据库的性能产生瓶颈的时候，我们可能会对数据库进行分区，这里所说的分区指的是物理分区，分区之后可能不同的库就处于不同的服务器上了，这个时候单个数据库的ACID已经不能适应这种情况了，而在这种ACID的集群环境下，再想保证集群的ACID几乎是很难达到，或者即使能达到那么效率和性能会大幅下降，最为关键的是再很难扩展新的分区了，这个时候如果再追求集群的ACID会导致我们的系统变得很差，这时我们就需要引入一个新的理论原则来适应这种集群的情况，就是 CAP 原则或者叫CAP定理，那么CAP定理指的是什么呢？&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;h4>CAP定理&lt;/h4>&lt;p>&lt;br>&lt;/p>&lt;p>CAP定理是由加州大学伯克利分校Eric Brewer教授提出来的，他指出WEB服务无法同时满足一下3个属性：&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;ul>&lt;li>&lt;p>一致性(Consistency) ： 客户端知道一系列的操作都会同时发生(生效)&lt;/p>&lt;/li>&lt;li>&lt;p>可用性(Availability) ： 每个操作都必须以可预期的响应结束&lt;/p>&lt;/li>&lt;li>&lt;p>分区容错性(Partition tolerance) ： 即使出现单个组件无法可用,操作依然可以完成&lt;/p>&lt;/li>&lt;/ul>&lt;p>&lt;br>&lt;/p>&lt;p>具体地讲在分布式系统中，在任何数据库设计中，一个Web应用至多只能同时支持上面的两个属性。显然，任何横向扩展策略都要依赖于数据分区。因此，设计人员必须在一致性与可用性之间做出选择。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>这个定理在迄今为止的分布式系统中都是适用的！&amp;nbsp;为什么这么说呢？&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>这个时候有同学可能会把数据库的2PC（两阶段提交）搬出来说话了。OK，我们就来看一下数据库的两阶段提交。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>对数据库分布式事务有了解的同学一定知道数据库支持的2PC，又叫做 XA Transactions。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>MySQL从5.5版本开始支持，SQL Server 2005 开始支持，Oracle 7 开始支持。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>其中，XA 是一个两阶段提交协议，该协议分为以下两个阶段：&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;ul>&lt;li>&lt;p>第一阶段：事务协调器要求每个涉及到事务的数据库预提交(precommit)此操作，并反映是否可以提交.&lt;/p>&lt;/li>&lt;li>&lt;p>第二阶段：事务协调器要求每个数据库提交数据。&lt;/p>&lt;/li>&lt;/ul>&lt;p>&lt;br>&lt;/p>&lt;p>其中，如果有任何一个数据库否决此次提交，那么所有数据库都会被要求回滚它们在此事务中的那部分信息。这样做的缺陷是什么呢? 咋看之下我们可以在数据库分区之间获得一致性。&lt;/p></description></item><item><title>建站仿站大师：对建站来说，选择虚拟主机有哪些优点和缺点</title><link>https://pangyd.com/post/135/</link><pubDate>Mon, 25 Dec 2017 12:31:21 +0800</pubDate><guid>https://pangyd.com/post/135/</guid><description>&lt;div id="img-content">&lt;div class="rich_media_content " id="js_content">&lt;p>&lt;span>随着互联网的发展和进步，主机商在提供多种主机种类的同时，也提供着应有尽有的主机方案，如此一来，站长们就可以有多种选择。在建站时，站长可以在虚拟主机、VPS主机、云主机、服务器等主机类型中作出选择。其中不乏有很多人会选择虚拟主机，这取决于虚拟主机独特的优势。但是事情都有两面性，虚拟主机也是如此，也有自身的缺点。&amp;nbsp;&lt;/span>&lt;br>&lt;span>其实对建站来说，正确认识所选虚拟主机有哪些优点和缺点才是明智的做法。&amp;nbsp;&lt;/span>&lt;br>&lt;span>选择虚拟主机的优点：&amp;nbsp;&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;strong>&lt;span>一.节省建站成本&amp;nbsp;&lt;/span>&lt;/strong>&lt;br>&lt;span>　　如果您搭建个人网站，或者为中小型企业搭建网站，选择虚拟主机是最合理的。因为如果您选择了独立服务器，不仅造成网站资源的浪费，也会大大增加建站的成本。而选择虚拟主机在满足建站的需求的前提下，还能为您节省建站成本。&amp;nbsp;&lt;/span>&lt;br>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;strong>&lt;span>二.操作简单，利于网站管理&amp;nbsp;&lt;/span>&lt;/strong>&lt;br>&lt;span>　　虚拟主机简单易操作的优点，更是受新手站长的喜爱。因为在虚拟主机的控制面板上，通常会对一些设置作出明确的标识，即使您不懂技术也能很容易就能上手操作，这对新手简直是福音。&amp;nbsp;&lt;/span>&lt;br>&lt;strong>&lt;span>&lt;br>&lt;/span>&lt;/strong>&lt;/p>&lt;p>&lt;strong>&lt;span>三.即买即用&amp;nbsp;&lt;/span>&lt;/strong>&lt;br>&lt;span>　　在主机商选购好虚拟主机，只有提交申请后主机商就可立即为您开通。这种即买即用的方式，在很大程度上为您节省了建站的时间。&amp;nbsp;&lt;/span>&lt;br>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;strong>&lt;span>四.升级比较容易&amp;nbsp;&lt;/span>&lt;/strong>&lt;br>&lt;span>　　随着网站需求的增大，您可能需要对主机进行升级。这时，只需您提交一下工单，主机商就会帮您自动升级。&amp;nbsp;&lt;/span>&lt;br>&lt;span>选择虚拟主机的缺点：&amp;nbsp;&lt;/span>&lt;br>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>1.某些功能会受到限制&amp;nbsp;&lt;/span>&lt;br>&lt;span>　　虚拟主机毕竟是共享一台服务器的资源，所以主机商为了在服务器上挂更多的网站，一定会对流量、资源等作出一些限制，也会对如404页面等等一些功能上作出限制。&amp;nbsp;&lt;/span>&lt;br>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>2.网站速度缓慢&amp;nbsp;&lt;/span>&lt;br>&lt;span>　　虚拟主机又称为共享主机，因此在多个网站共同运行时，您网站的速度也会随之下降，进而对SEO优化的一些因素也造成了不利的影响。&amp;nbsp;&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>3.其他网站被攻击时，自己的网站会受到影响&amp;nbsp;&lt;/span>&lt;br>&lt;/p>&lt;p>&lt;span>　　因为是共享同台服务器资源，所以只要其中一个网站受到攻击或者被降权，都会牵连其他的网站。&amp;nbsp;&lt;/span>&lt;br>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>4.考虑的比较多&amp;nbsp;&lt;/span>&lt;br>&lt;span>　　建站在选择虚拟主机时，您要明确下主机商所提供的虚拟主机有哪些功能，以防没有自己需要的特定功能。&amp;nbsp;&lt;/span>&lt;br>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>以上简单的阐述了虚拟主机的优缺点。要明确知道这些，而且在搭建网站时，仔细分析一下各个主机的优缺点，以期为自己的网站选择一个最合适的主机。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>链接:https://mp.weixin.qq.com/s/lTYsRFzu4YfqGsg-GIeLLg&amp;nbsp;&lt;/p>&lt;/div>&lt;/div></description></item><item><title>深圳职业学院图书馆</title><link>https://pangyd.com/post/192/</link><pubDate>Wed, 06 Dec 2017 18:12:54 +0800</pubDate><guid>https://pangyd.com/post/192/</guid><description>&lt;p>演示：&lt;a target="_blank" href="https://pangyd.com/zl/web/szxy/">点击&lt;/a>&lt;/p>&lt;p>下载：&lt;a target="_blank" href="https://pangyd.com/zl/web/szxy.zip">点击&lt;/a>&lt;/p></description></item><item><title>程序员6大幽默的编程语录，比尔盖茨诠释了什么叫编程进度！</title><link>https://pangyd.com/post/188-6/</link><pubDate>Fri, 01 Dec 2017 21:23:53 +0800</pubDate><guid>https://pangyd.com/post/188-6/</guid><description>&lt;p>在很多人的印象当中，程序员是比较内向、呆板的。&lt;/p>&lt;p>实际上，这是一个很有幽默感的群体。&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>下面w3cschool就让小伙伴们感受一下程序员们的幽默感，程序员幽默起来很吓人。&lt;/p>&lt;p>0、编程就像性一样:一时犯错,终生维护。——Michael Sinz&lt;/p>&lt;p>改bug是消除BUG的过程，编程就是将bug放进的过程。&lt;/p>&lt;p>你的代码写的有多聪明，你就要用更聪明的方式DEBUG。&lt;/p>&lt;p>正所谓魔高一尺，道高一丈。&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>1、编程时要保持这种心态：就好象将来要维护你这些代码的人是一位残暴的精神病患者，而且他知道你住在哪。——MartinGolding&lt;/p>&lt;p>并非所有的程序员写的代码是易于维护的，有些程序员代码没有注释的习惯，或者违反了编程惯例，导致了代码难以维护。&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>2、如果没能一次成功，那就叫它1.0版吧。&lt;/p>&lt;p>3、用代码行数来衡量程序的开发进度，就好比用重量来衡量飞机的制造进度。—— 比尔·盖茨&lt;/p>&lt;p>一直以来，很赞同一个观点：码20万行程序和编20万行工业级质量的代码，体验是完全不同的!&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>4、有的时候宁愿付钱让你周一在床上待着，也不想让你用这周剩下的时间去调试你在周一所写的代码。 —— 丹·所罗门&lt;/p>&lt;p>5、Talk is cheap, show me the code。——Linus之父&lt;/p>&lt;p>来看看神翻译：“废话少说，放码过来”。&lt;/p></description></item><item><title>格力地产网站</title><link>https://pangyd.com/post/187/</link><pubDate>Thu, 30 Nov 2017 14:42:35 +0800</pubDate><guid>https://pangyd.com/post/187/</guid><description>&lt;p>演示：&lt;a target="_self" href="https://pangyd.com/zl/web/pangyudongDC/">点击&lt;/a>&lt;/p>&lt;p>下载：&lt;a target="_self" href="https://pangyd.com/zl/web/pangyudongDC.zip">点击&lt;/a>&lt;/p></description></item><item><title>我们JAVA开发学习的七大作为</title><link>https://pangyd.com/post/186-java/</link><pubDate>Wed, 29 Nov 2017 19:15:12 +0800</pubDate><guid>https://pangyd.com/post/186-java/</guid><description>&lt;p style="text-align: center">&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-size="603|434">&lt;/p>&lt;p>&lt;span>Java可以编写桌面应用程序、Web应用程序、分布式系统和嵌入式系统应用程序等。以下是小编搜索整理的关于JAVA开发学习的七大步骤，供参考借鉴，希望对大家有所帮助!&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>1、多动手&lt;/span>&lt;/p>&lt;p>　　学编程语言不仅仅是从理论上的学习，更重要的是要利用这门语言为你的思想服务。理解这门语言是首要的，但是要达到心领神会、融会贯通就必须勤动手，多去时间，多编一些例子。计算机科学是注重实践的学科，成功的软件开发人员无不经过大量的上机锻炼，只有理论和实践相结合才能真正掌握只是和技能。&lt;/p>&lt;p>&lt;span>　　2、多动脑&lt;/span>&lt;/p>&lt;p>　　对于Java语言的学习，不仅仅是对语言本身的学习，更重要的是面向对象思想的简历过程，如果想把Java学习提升到一个更高的层次，Java私塾建议从一开始就用面向对象的思维方式去面对你所接触的每件事。&lt;/p>&lt;p>&lt;span>　　3、多查API文档&lt;/span>&lt;/p>&lt;p>　　Java提供了大量的类以满足网络化、多线程、面向对象的需要。这就是J2SEAPI，它是Java编程的基本方法，也是编程过程中所不断利用的资源。Java的学习过程不仅仅是基本语法的学习，更多的是去学习和掌握它所提供的API类库。对于所接触到的类，方法，都去仔细去阅读文档的说明，再用自己编写的实例去此时一下。&lt;/p>&lt;p>&lt;span>　　4、约束自己，规范编码习惯&lt;/span>&lt;/p>&lt;p>　　养成良好的编码习惯对于一个程序员来讲具有相当大的意义。一方面良好的编程习惯对于减少编码过程中一些人为的错误能起到主动避免的作用;另一方面一段程序写的好坏，不仅仅是功能上的实现，更主要的是可读性，可维护性，没有任何人愿意去阅读一段没有顺序，杂乱无章的代码。建议大家在编码的时候要时刻想到：如果这段代码给别人看，别人是否看得懂，条理是否清楚。&lt;/p>&lt;p>&lt;span>　　5、用有意义的名字&lt;/span>&lt;/p>&lt;p>　　名字，是一个标识，是一种有内涵的简单表述。在编写程序的过程中，为每个类、每个方法起一个有意义的名字。在程序阅读的过程中，看到这个名字就可以知道她多完成的功能。&lt;/p>&lt;p>&lt;span>　　6、添加适量的注释&lt;/span>&lt;/p>&lt;p>　　注释不仅仅是对程序逻辑处理的一种注释，更多的是提高了程序的可读性和可维护性。做为一个软件产品，哪怕只是一个小小的功能的实现，其中不同的变量及方法可能很多，虽然在命名的过程中要使用有意义的名字，但也不能完全涵盖变量及方法的功能及内涵，多为了提高程序的可读性，添加一定的注释是非常有必要的。合理的注释不仅能起到美化程序的作用还能提高程序可读性和维护性。&lt;/p>&lt;p>&lt;span>　　7、相信自己&lt;/span>&lt;/p>&lt;p>　　相信自己包括两方面，一是相信自己的能力，二是相信自己的答案。&lt;/p>&lt;p>　　相信自己的能力就是要相信自己具有解决问题的能力。一个程序员的好坏并不是直接决定于是否能编写出好的代码，更重要的是能否自己去解决调试过程中遇到的任何问题，很少有一个程序员写出的代码一次成功，只有在不断的调试，修正中才能编写出真正的好代码。调试、解决问题的过程就是自己学习提高的过程。&lt;/p>&lt;p>　　相信自己的答案就是要相信自己的程序运行的结果。对于不同的问题在不同的资料上可能有不同的答案，就像小马过河一样，不同的人可能有不同的答案，所以不要去盲目的相信任何人，要相信自己。&lt;/p>&lt;div>&lt;br>&lt;/div></description></item><item><title>五分钟学会 Kotlin 语法</title><link>https://pangyd.com/post/184-kotlin/</link><pubDate>Wed, 29 Nov 2017 11:03:22 +0800</pubDate><guid>https://pangyd.com/post/184-kotlin/</guid><description>&lt;pre>&lt;div>&lt;h2>为什么使用Kotlin&lt;/h2>
&lt;p>项目一期在收尾了终于有时间折腾了，一个多月以来Kotlin从入门到现在，坚持用来开发的切身感受。因为语法与Java的区别挺大的一开始很想放弃，如果不是因为项目在使用，想必很少人会尝试这样一门小众语言，但是习惯后会发现这些年究竟浪费多少时间在写无用的Java代码了，Kotlin在兼容Java的基础上还能大大提升开发效率。Kotlin有许多特性但对于开发来说，快速适应和学习更为重要，很多时候我们都是在不明白其原因就开始使用的，正如我们不可能把Retrofit原理研究透才使用它。只要它足够稳定成熟，并能有效的提升开发效率都是值得尝试的。鄙人不才，目前使用Kotlin的原因主要是因为它语法简洁，支持lambda表达式，强大的when语法，不用写分号结尾，光是这些就足以让我喜欢Kotlin。至于空安全之类的特性，毕竟服务端数据类型太多null了并没多大感触，这些特性在实际应用中潜移默化的就吸收了，以至于现在遇到几个Java编写的代码，都有些不适应了。&lt;/p>
&lt;h2>修改说明&lt;/h2>
&lt;p>突然火了一脸懵逼，Google IO的影响真是不容小觑。避免误人子弟还是修改下比较好，也就把上一篇文章的基础知识也搬迁过来，对条件判断&lt;code>when&lt;/code>还有空判断处理进行了修改，添加了&lt;code>lambda&lt;/code>说明，移除过期链接。&lt;/p>
&lt;h2>Kotlin 基本语法&lt;/h2>
&lt;p>先说个学习Kotlin语法的小窍门，将代码用Java写好，然后&lt;code>Code/Conver Java File to Kotlin File&lt;/code>转换成Kotlin代码，或者将Java代码复制到Kotlin文件会提示转换也是挺方便的，比较差异很容易就能理解了，一开始难免不适应习惯后相信你一定会喜欢上Kotlin&lt;/p>
&lt;p>1). 定义&lt;/p>
&lt;p>忘掉Java的那一套写法不然会很不适应的，Kotlin有自己的特性不该被Java的思维所束缚。在Kotlin中常量用&lt;code>val&lt;/code>声明，变了用&lt;code>var&lt;/code>声明，关键字在前面，类型以冒号&lt;code>:&lt;/code>隔开在后面，也可以省略直接赋值，类型后带问号&lt;code>?&lt;/code>表示可为空类型(默认空安全)。&lt;br>
常量&lt;code>val&lt;/code>延迟加载&lt;code>by lazy{}&lt;/code>，默认线程安全关闭线程安全&lt;code>lazy(LazyThreadSafetyMode.NONE){}&lt;/code>，变量&lt;code>var&lt;/code>延迟加载&lt;code>lateinit&lt;/code>。&lt;/p>
&lt;pre class="hljs java">&lt;code class="java">&lt;span class="hljs-comment">//常量数组int[][][] arrs = new int[3][2][1];&lt;/span>
val arrs = Array(&lt;span class="hljs-number">3&lt;/span>) { Array(&lt;span class="hljs-number">2&lt;/span>) { IntArray(&lt;span class="hljs-number">1&lt;/span>) } }
&lt;span class="hljs-comment">//空安全变量&lt;/span>
var str: String = &lt;span class="hljs-string">"hello"&lt;/span>
var str1 = &lt;span class="hljs-string">"word"&lt;/span>
&lt;span class="hljs-comment">//可为空字符串变量&lt;/span>
var str2: String? = &lt;span class="hljs-keyword">null&lt;/span>

&lt;/code>&lt;/pre>
&lt;p>2). 条件&lt;/p>
&lt;p>&lt;code>if...else&lt;/code> 正常使用，不过移除了&lt;code>switch&lt;/code>用更强大的&lt;code>when&lt;/code>替代，when子式可以是常量、变量、返回数值的表达式、返回Boolean值的表达式，强大到用来替换&lt;code>if...else if&lt;/code>&lt;/p>
&lt;pre class="hljs java">&lt;code class="java">&lt;span class="hljs-comment">// 测试值 x = 0, -1, 1, 2, 3, 6, 10&lt;/span>
var x = &lt;span class="hljs-number">10&lt;/span>
when (x) {
 &lt;span class="hljs-comment">//常量&lt;/span>
 &lt;span class="hljs-number">2&lt;/span> -&amp;gt; println(&lt;span class="hljs-string">"等于2"&lt;/span>)
 &lt;span class="hljs-comment">//数值表达式&lt;/span>
 &lt;span class="hljs-keyword">if&lt;/span> (x &amp;gt; &lt;span class="hljs-number">0&lt;/span>) &lt;span class="hljs-number">1&lt;/span> &lt;span class="hljs-keyword">else&lt;/span> -&lt;span class="hljs-number">1&lt;/span> -&amp;gt; println(&lt;span class="hljs-string">"大于0并等于1，或小于0并等于-1"&lt;/span>)
 &lt;span class="hljs-comment">//Boolean类型表达式&lt;/span>
 in &lt;span class="hljs-number">1&lt;/span>..&lt;span class="hljs-number">5&lt;/span> -&amp;gt; println(&lt;span class="hljs-string">"范围匹配1-5"&lt;/span>)
 !in &lt;span class="hljs-number">6&lt;/span>..&lt;span class="hljs-number">9&lt;/span> -&amp;gt; println(&lt;span class="hljs-string">"不是6-9"&lt;/span>)
 is Int -&amp;gt; println(&lt;span class="hljs-string">"类型判断"&lt;/span>)
 &lt;span class="hljs-keyword">else&lt;/span> -&amp;gt; println(&lt;span class="hljs-string">"else"&lt;/span>)
}
&lt;span class="hljs-comment">// 代替if...else if&lt;/span>
when{
 x &amp;gt; &lt;span class="hljs-number">6&lt;/span> &amp;amp;&amp;amp; x &amp;lt;= &lt;span class="hljs-number">10&lt;/span> -&amp;gt; println(&lt;span class="hljs-string">"大于6小于等于10"&lt;/span>)
 x &amp;lt; &lt;span class="hljs-number">6&lt;/span> -&amp;gt; println(&lt;span class="hljs-string">"小于6"&lt;/span>)
 &lt;span class="hljs-keyword">else&lt;/span> -&amp;gt; println(&lt;span class="hljs-string">"else"&lt;/span>)
}
&lt;/code>&lt;/pre>
&lt;p>3). 循环&lt;/p></description></item><item><title>请不要自称自己是程序员</title><link>https://pangyd.com/post/183/</link><pubDate>Mon, 27 Nov 2017 19:51:25 +0800</pubDate><guid>https://pangyd.com/post/183/</guid><description>&lt;p>&lt;span>每年都有无数年轻程序员，加入软件行业。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>他们在学校里学过编程，但是对这个行业的现实一无所知。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;img data-src="https://pangyd.com/uploads/2017/11/74c10f869f038762.jpg" class="" data-ratio="0.660377358490566" data-w="636" data-type="jpeg" width="333px" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-fail="0">&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>Patrick McKenzie&amp;nbsp;是美国一家小软件公司的老板，他写了一篇长文，介绍这个行业的一些实际情况。我看了以后很感慨，有些地方很受启发。我选择了一部分，翻译如下。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;h2>&lt;span>&lt;/span>&lt;/h2>&lt;p>&lt;/p>&lt;section class="" data-mpa-template-id="489541" data-mpa-color="#ffffff" data-mpa-category="title">&lt;section label="Copyright Reserved by ipaiban.com." donone="shifuMouseDown('shifu_t_016')" mpa-is-content="t">&lt;span>&lt;span>一、90% 的编程工作来自内部软件&lt;/span>&lt;/span>&lt;/section>&lt;/section>&lt;p>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>计算机专业的学生，可能有一种印象，觉得大部分程序员，都在编写公开出售的软件或者通用软件。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>这种看法是不对的。大部分程序员，实际上编写的是不公开的企业内部软件，比如追踪费用的软件、优化装运成本的软件、帮助记账的软件、设计新部件的软件、计算保单价格的软件、识别恶意订单的软件等等。各种各样的商业公司，开发内部软件，解决它们自己的问题。市场上对程序员的大部分需求来源于此，只有极少数程序员直接编写面向外部顾客的软件。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>内部软件的开发，通常非常乏味，令人厌倦。因为它们的技术复杂性低、技术决策非常保守、预算很少、缺乏长远考虑。但是，世界上大部分编程工作都是这种。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;h2>&lt;span>&lt;/span>&lt;/h2>&lt;p>&lt;/p>&lt;section class="" data-mpa-template-id="489541" data-mpa-color="#ffffff" data-mpa-category="title">&lt;section label="Copyright Reserved by ipaiban.com." donone="shifuMouseDown('shifu_t_016')" mpa-is-content="t">&lt;span>&lt;span>二、别人雇你的目的，是让你创造利润，不是让你编程&lt;/span>&lt;/span>&lt;/section>&lt;/section>&lt;p>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;img data-type="gif" data-src="https://pangyd.com/uploads/2017/11/74c10f869f038762.jpg" data-copyright="0" class=" __bg_gif" data-ratio="0.562" data-w="500" width="382px" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-order="0" data-fail="0">&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;br>&lt;/p>&lt;p>&lt;span>商业公司最关心的（或者说唯一在乎的）事情，就是增加收入、降低成本。因此，它们实际上需要的不是程序员，而是能够帮助它们增加收入、降低成本的人。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>开发优美的软件，解决技术难题，编写没有 bug 的代码，这些都不是商业公司的目的。它们雇佣你，是为了让你帮它们完成某个可以增加收入、降低成本的项目，而不是为了让你追求个人的软件成就。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>你对于公司的唯一价值，就在于能多大程度上为它们增加收入、降低成本。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;h2>&lt;span>&lt;/span>&lt;/h2>&lt;p>&lt;/p>&lt;section class="" data-mpa-template-id="489541" data-mpa-color="#ffffff" data-mpa-category="title">&lt;section label="Copyright Reserved by ipaiban.com." donone="shifuMouseDown('shifu_t_016')" mpa-is-content="t">&lt;span>&lt;span>三、不要自称为程序员&lt;/span>&lt;/span>&lt;/section>&lt;/section>&lt;p>&lt;/p></description></item><item><title>java mail实现Email的发送,完整代码</title><link>https://pangyd.com/post/182-java-mailemail/</link><pubDate>Sun, 26 Nov 2017 18:34:36 +0800</pubDate><guid>https://pangyd.com/post/182-java-mailemail/</guid><description>&lt;p>1、对应用程序配置邮件会话&lt;/p>&lt;p>javax.mail.Session保存邮件系统的配置属性和提供用户验证的信息，发送email首先要获取session对象。&lt;/p>&lt;p>(1)Session.getInstance(java.util.Properties)获取非共享的session对象&lt;/p>&lt;p>(2)Session.getDefaultInstance(java.utilProperties)获取共享的session对象&lt;/p>&lt;p>&amp;nbsp;&amp;nbsp;&amp;nbsp; 两者都必须建立Properties prop=new Properties()对象;&lt;/p>&lt;p>&lt;span>注意：&lt;/span>一般对单用户桌面应用程序使用共享Session对象。&lt;/p>&lt;p>用SMTP协议发送Email时通常要设置mail.smtp.host(mail.protocol.host协议特定邮件服务器名)属性。&lt;/p>&lt;p>prop.put("mail.smtp.host","smtp.mailServer.com");&lt;/p>&lt;p>Session mailSession=Session.getInstance(prop);&lt;/p>&lt;p>&lt;span>注意：&lt;/span>在真正使用创建的过程中，往往会让我们验证密码，这是我们要写一个密码验证类。javax.mail.Authenticator是一个抽象类，我们要写MyAuthenticator的密码验证类，该类继承Authenticator实现：&lt;/p>&lt;p>&amp;nbsp;protected PasswordAuthentication getPasswordAuthentication(){&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return new PasswordAuthentication(String userName, String password);&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br>&amp;nbsp; }&lt;/p>&lt;p>这时我们创建Session对象：&lt;/p>&lt;p>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Session mailSession=Session.getInstance(prop,new MyAuthenticator(userName,Password));&lt;/p>&lt;p>&lt;span>并且要设置使用验证&lt;/span>：prop.put("mail.smtp.auth","true");&lt;/p>&lt;p>&lt;span>使用 STARTTLS安全连接&lt;/span>:prop.put("mail.smtp.starttls.enable","true");&lt;/p>&lt;p>2、配置邮件会话之后，要编写消息&lt;/p>&lt;p>要编写消息就要生成javax.mail.Message子类的实例或对Internet邮件使用javax.mail.interet.MimeMessage类。&lt;/p>&lt;p>(1)建立MimeMessage对象&lt;/p>&lt;p>MimeMessage扩展抽象的Message类，构造MimeMessage对象：&lt;/p>&lt;p>MimeMessage message=new MimeMessage(mailSession);&lt;/p>&lt;p>(2)消息发送者、日期、主题&amp;nbsp;&lt;/p>&lt;p>message.setFrom(Address theSender);&lt;/p>&lt;p>message.setSentDate(java.util.Date theDate);&lt;/p>&lt;p>message.setSubject(String theSubject);&lt;/p>&lt;p>(3)设置消息的接受者与发送者（寻址接收）&lt;/p>&lt;p>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; setRecipient(Message.RecipientType type , Address theAddress)、setRecipients(Message.RecipientType type , Address[] theAddress)、addRecipient(Message.RecipientType type , Address theAddress)、addRecipients(Message.RecipientType type,Address[] theAddress)方法都可以指定接受者类型，但是一般用后两个，这样可以避免意外的替换或者覆盖接受者名单。定义接受者类型：&lt;/p>&lt;p>Message.RecipientType.TO：消息接受者&lt;/p>&lt;p>Message.RecipientType.CC：消息抄送者&lt;/p>&lt;p>Message.RecipientType.BCC：匿名抄送接收者(其他接受者看不到这个接受者的姓名和地址)&lt;/p>&lt;p>(4)设置消息内容&lt;/p>&lt;p>JavaMail基于JavaBean Activation FrameWork(JAF)，JAF可以构造文本消息也可以支持附件。&lt;/p>&lt;p>设置消息内容时，要提供消息的内容类型-----即方法签名:&lt;/p></description></item><item><title>深入理解Java虚拟机到底是什么</title><link>https://pangyd.com/post/180-java/</link><pubDate>Fri, 24 Nov 2017 22:54:49 +0800</pubDate><guid>https://pangyd.com/post/180-java/</guid><description>&lt;p>什么是Java虚拟机&lt;/p>&lt;div class="content rich" data-reactid=".0.1.0.0.0.1.1.1">&lt;p>作为一个Java程序员，我们每天都在写Java代码，我们写的代码都是在一个叫做Java虚拟机的东西上执行的。但是如果要问什么是虚拟机，恐怕很多人就会模棱两可了。在本文中，我会写下我对虚拟机的理解。因为能力所限，可能有些地方描述的不够欠当。如果你有不同的理解，欢迎交流。&lt;/p>&lt;p>我们都知道java程序必须在虚拟机上运行。那么虚拟机到底是什么呢？先看网上搜索到的比较靠谱的解释：&lt;/p>&lt;p>虚拟机是一种抽象化的计算机，通过在实际的计算机上仿真模拟各种计算机功能来实现的。Java虚拟机有自己完善的硬体架构，如处理器、堆栈、寄存器等，还具有相应的指令系统。JVM屏蔽了与具体操作系统平台相关的信息，使得Java程序只需生成在Java虚拟机上运行的目标代码（字节码），就可以在多种平台上不加修改地运行。&lt;/p>&lt;p>这种解释应该算是正确的，但是只描述了虚拟机的外部行为和功能，并没有针对内部原理做出说明。一般情况下我们不需要知道虚拟机的运行原理，只要专注写java代码就可以了，这也正是虚拟机之所以存在的原因--屏蔽底层操作系统平台的不同并且减少基于原生语言开发的复杂性，使java这门语言能够跨各种平台（只要虚拟机厂商在特定平台上实现了虚拟机），并且简单易用。这些都是虚拟机的外部特性，但是从这些信息来解释虚拟机，未免太笼统了，无法让我们知道内部原理。&lt;/p>&lt;p>从进程的角度解释JVM&lt;/p>&lt;p>让我们尝试从操作系统的层面来理解虚拟机。我们知道，虚拟机是运行在操作系统之中的，那么什么东西才能在操作系统中运行呢？当然是进程，因为进程是操作系统中的执行单位。可以这样理解，当它在运行的时候，它就是一个操作系统中的进程实例，当它没有在运行时（作为可执行文件存放于文件系统中），可以把它叫做程序。&lt;/p>&lt;p>对命令行比较熟悉的同学，都知道其实一个命令对应一个可执行的二进制文件，当敲下这个命令并且回车后，就会创建一个进程，加载对应的可执行文件到进程的地址空间中，并且执行其中的指令。下面对比C语言和Java语言的HelloWorld程序来说明问题。&lt;/p>&lt;p>首先编写C语言版的HelloWorld程序。&lt;/p>&lt;p>&lt;span>[cpp]&lt;/span>view plain copy&lt;/p>&lt;p>#include&lt;/p>&lt;p>#include&lt;/p>&lt;p>int main(void) {&lt;/p>&lt;p>printf("hello world\n");&lt;/p>&lt;p>return 0;&lt;/p>&lt;p>}&lt;/p>&lt;p>编译C语言版的HelloWorld程序：&lt;/p>&lt;p>&lt;span>[plain]&lt;/span>view plain copy&lt;/p>&lt;p>gcc HelloWorld.c -o HelloWorld&lt;/p>&lt;p>运行C语言版的HelloWorld程序：&lt;/p>&lt;p>&lt;span>[plain]&lt;/span>view plain copy&lt;/p>&lt;p>zhangjg@linux:/deve/workspace/HelloWorld/src$ ./HelloWorld&lt;/p>&lt;p>hello world&lt;/p>&lt;p>gcc编译器编译后的文件直接就是可被操作系统识别的二进制可执行文件，当我们在命令行中敲下 ./HelloWorld这条命令的时候， 直接创建一个进程， 并且将可执行文件加载到进程的地址空间中， 执行文件中的指令。&lt;/p>&lt;p>作为对比， 我们看一下Java版HelloWord程序的编译和执行形式。&lt;/p>&lt;p>首先编写源文件HelloWord.java ：&lt;/p>&lt;p>&lt;span>[java]&lt;/span>view plain copy&lt;/p>&lt;p>public class HelloWorld {&lt;/p>&lt;p>public static void main(String[] args) {&lt;/p>&lt;p>}&lt;/p>&lt;p>}&lt;/p>&lt;p>编译Java版的HelloWorld程序：&lt;/p>&lt;p>&lt;span>[java]&lt;/span>view plain copy&lt;/p>&lt;p>zhangjg@linux:/deve/workspace/HelloJava/src$ javac HelloWorld.java&lt;/p>&lt;p>zhangjg@linux:/deve/workspace/HelloJava/src$ ls&lt;/p>&lt;p>HelloWorld.class HelloWorld.java&lt;/p></description></item><item><title>传智博客学院</title><link>https://pangyd.com/post/179/</link><pubDate>Thu, 23 Nov 2017 15:19:54 +0800</pubDate><guid>https://pangyd.com/post/179/</guid><description>&lt;p>&lt;a target="_blank" href="https://pangyd.com/zl/web/czbk/index.html">演示&lt;/a>&lt;/p>&lt;p>&lt;a target="_self" href="https://pangyd.com/zl/web/czbk.zip">下载&lt;/a>&lt;/p></description></item><item><title>Java 注解全面解析</title><link>https://pangyd.com/post/178-java/</link><pubDate>Wed, 22 Nov 2017 21:06:20 +0800</pubDate><guid>https://pangyd.com/post/178-java/</guid><description>&lt;p style="text-align: center">&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-size="550|338">&lt;/p>&lt;p>注解定义看起来很像接口的定义。事实上，与其他任何接口一样，注解也将会编译成class文件。&lt;/p>&lt;blockquote>&lt;p>@Target(ElementType.Method)&lt;/p>&lt;p>@Retention(RetentionPolicy.RUNTIME)&lt;/p>&lt;p>public @interface Test {}&lt;/p>&lt;/blockquote>&lt;p>除了@符号以外，@Test的定义很像一个空的接口。定义注解时，需要一些元注解（meta－annotation），如@Target和@Retention&lt;/p>&lt;p>@Target用来定义注解将应用于什么地方（如一个方法或者一个域）&lt;/p>&lt;p>@Retention用来定义注解在哪一个级别可用，在源代码中（source），类文件中（class）或者运行时（runtime）&lt;/p>&lt;p>在注解中，一般都会包含一些元素以表示某些值。当分析处理注解时，程序可以利用这些值。没有元素的注解称为标记注解（marker annotation）&lt;/p>&lt;p>四种元注解，元注解专职负责注解其他的注解，所以这四种注解的Target值都是ElementType.ANNOTATION_TYPE&lt;/p>&lt;table width="736" class="layui-table">&lt;tbody>&lt;tr class="firstRow">&lt;th style="text-align: center">注解&lt;/th>&lt;th style="text-align: center">说明&lt;/th>&lt;/tr>&lt;tr>&lt;td>@Target&lt;/td>&lt;td>表示该注解可以用在什么地方，由ElementType枚举定义&lt;br data-filtered="filtered">CONSTRUCTOR：构造器的声明&lt;br data-filtered="filtered">FIELD：域声明（包括enum实例）&lt;br data-filtered="filtered">LOCAL_VARIABLE：局部变量声明&lt;br data-filtered="filtered">METHOD：方法声明&lt;br data-filtered="filtered">PACKAGE：包声明&lt;br data-filtered="filtered">PARAMETER：参数声明&lt;br data-filtered="filtered">TYPE：类、接口（包括注解类型）或enum声明&lt;br data-filtered="filtered">ANNOTATION_TYPE：注解声明（应用于另一个注解上）&lt;br data-filtered="filtered">TYPE_PARAMETER：类型参数声明（1.8新加入）&lt;br data-filtered="filtered">TYPE_USE：类型使用声明（1.8新加入）&lt;br data-filtered="filtered">PS：当注解未指定Target值时，此注解可以使用任何元素之上，就是上面的类型&lt;/td>&lt;/tr>&lt;tr>&lt;td>@Retention&lt;/td>&lt;td>表示需要在什么级别保存该注解信息，由RetentionPolicy枚举定义&lt;br data-filtered="filtered">SOURCE：注解将被编译器丢弃（该类型的注解信息只会保留在源码里，源码经过编译后，注解信息会被丢弃，不会保留在编译好的class文件里）&lt;br data-filtered="filtered">CLASS：注解在class文件中可用，但会被VM丢弃（该类型的注解信息会保留在源码里和class文件里，在执行的时候，不会加载到虚拟机（JVM）中）&lt;br data-filtered="filtered">RUNTIME：VM将在运行期也保留注解信息，因此可以通过反射机制读取注解的信息（源码、class文件和执行的时候都有注解的信息）&lt;br data-filtered="filtered">PS：当注解未定义Retention值时，默认值是CLASS&lt;/td>&lt;/tr>&lt;tr>&lt;td>@Documented&lt;/td>&lt;td>表示注解会被包含在javaapi文档中&lt;/td>&lt;/tr>&lt;tr>&lt;td>@Inherited&lt;/td>&lt;td>允许子类继承父类的注解&lt;/td>&lt;/tr>&lt;/tbody>&lt;/table>&lt;p>&lt;/p>&lt;section class="">&lt;section data-by="96weixin">&lt;section style="text-align: center">&lt;section>&lt;img data-src="https://pangyd.com/uploads/2017/11/74c10f869f038762.jpg" data-type="jpeg" class="" data-ratio="1.09" data-w="100" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-fail="0">&lt;/section>&lt;section>&lt;h2>&lt;span>2. 注解元素&lt;/span>&lt;/h2>&lt;/section>&lt;/section>&lt;/section>&lt;/section>&lt;p>&lt;/p>&lt;p>&lt;span>– 注解元素可用的类型如下：&lt;/span>&lt;/p>&lt;p>– 所有基本类型（int,float,boolean,byte,double,char,long,short）&lt;/p>&lt;p>– String&lt;/p>&lt;p>– Class&lt;/p>&lt;p>– enum&lt;/p>&lt;p>– Annotation&lt;/p>&lt;p>– 以上类型的数组&lt;/p>&lt;p>如果使用了其他类型，那编译器就会报错。也不允许使用任何包装类型。注解也可以作为元素的类型，也就是注解可以嵌套。&lt;/p>&lt;p>元素的修饰符，只能用public或default。&lt;/p>&lt;p>&lt;span>– 默认值限制&lt;/span>&lt;/p>&lt;p>编译器对元素的默认值有些过分挑剔。首先，元素不能有不确定的值。也就是说，元素必须要么具有默认值，要么在使用注解时提供元素的值。&lt;/p>&lt;p>其次，对于非基本类型的元素，无论是在源代码中声明，还是在注解接口中定义默认值，都不能以null作为值。这就是限制，这就造成处理器很难表现一个元素的存在或缺失状态，因为每个注解的声明中，所有的元素都存在，并且都具有相应的值。为了绕开这个限制，只能定义一些特殊的值，例如空字符串或负数，表示某个元素不存在。&lt;/p>&lt;blockquote>&lt;p>@Target(ElementType.Method)&lt;/p>&lt;p>@Retention(RetentionPolicy.RUNTIME)&lt;/p></description></item><item><title>学习Java编程最有效的方法</title><link>https://pangyd.com/post/177-java/</link><pubDate>Tue, 21 Nov 2017 18:07:45 +0800</pubDate><guid>https://pangyd.com/post/177-java/</guid><description>&lt;p style="text-align: center">&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-size="550|338">&lt;/p>&lt;section data-author="Wxeditor">&lt;article class="" data-author="Wxeditor">&lt;section>&lt;section>&lt;p>有很多的Java程序员，在初期学习时，通常会对如何学习而感到迷茫。下面我就来分析下如何学好Java编程，相信能帮助那些正在处于迷茫状态的初学者。&lt;/p>&lt;/section>&lt;/section>&lt;/article>&lt;/section>&lt;p>&lt;/p>&lt;section data-author="Wxeditor">&lt;article class="" data-author="Wxeditor">&lt;section>&lt;h3 class="">&lt;span>1、培养兴趣&lt;/span>&lt;/h3>&lt;/section>&lt;/article>&lt;p>&lt;br>&lt;/p>&lt;/section>&lt;p>&lt;/p>&lt;p>&lt;span>兴趣是能够让你坚持下去的动力,如果只是把写程序作为谋生的手段的话，你会活的很累，多关心一些行业趣事，多想想盖茨。不是提倡天天做白日梦，但人要是没有了梦想，你觉得有味道吗？&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>可能像许多人一样，打打麻将，喝喝功夫茶，拜拜财神爷；每个月就有几万十几万甚至更多的进帐，凭空多出个"食利阶层"。你认为，这样有味道吗？有空多到一些程序员论坛转转，你会发现，他们其实很乐观幽默，时不时会冒出智慧的火花。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;/p>&lt;section data-author="Wxeditor">&lt;article class="" data-author="Wxeditor">&lt;section>&lt;h3 class="">&lt;span>2、要脚踏实地&lt;/span>&lt;/h3>&lt;/section>&lt;/article>&lt;p>&lt;br>&lt;/p>&lt;/section>&lt;p>&lt;/p>&lt;p>&lt;span>快餐式的学习不可取，欲速则不达，浮躁是现代人最普遍的心态，能怪谁？也许是贫穷落后了这么多年的缘故，就像当年的大跃进一样，都想大步跨入共产主义社会。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>现在的软件公司、客户、政府、学校、培训机构等等到处弥漫着浮躁之气。社会环境如是，我们不能改变，只能改变自己,闹市中的安宁，弥足珍贵。许多初学者C++/Java没开始学，立马使用VC/JBuilder,会使用VC/JBuilder开发一个HelloWorld程序，就忙不迭的向世界宣告，"我会软件开发了"，简历上也大言不惭地写上"精通VC/Java"。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>结果到软件公司面试时要么被三两下打发走了，要么被驳的体无完肤，无地自容。到处碰壁之后才知道捧起《Java编程思想》仔细钻研，早知如此何必当初呀。"你现在讲究简单方便，你以后的路就长了"，好象也是佛经中的劝戒。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;/p>&lt;section data-author="Wxeditor">&lt;article class="" data-author="Wxeditor">&lt;section>&lt;h3 class="">&lt;span>3、多实践，快实践&lt;/span>&lt;/h3>&lt;/section>&lt;/article>&lt;p>&lt;br>&lt;/p>&lt;/section>&lt;p>&lt;/p>&lt;p>&lt;span>任何事情，一旦考虑好了，就要马上上路，不要等到准备周全之后，再去干事情。假如事情准备考虑周全了再上路的话，别人恐怕捷足先登了。Java软件开发是一门工程学科，注重的就是实践，"君子动口不动手"对软件开发人员来讲根本就是错误的，他们提倡"动手至上"，但别害怕，他们大多温文尔雅，没有暴力倾向，虽然有时候蓬头垢面的一副"比尔盖茨"样。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>有前辈高人认为，学习编程的秘诀是：编程、编程、再编程，笔者深表赞同。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>不仅要多实践，而且要快实践。我们在看书的时候，不要等到你完全理解了才动手敲代码，而是应该在看书的同时敲代码，程序运行的各种情况可以让你更快更牢固的掌握知识点。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>加强英文阅读能力对学习Java编程来说，不要求英语,但不能一点不会,最起码像JAVAAPI文档这些东西还是要能看懂的,连猜带懵都可以；旁边再开启一个"金山词霸"。看多了就会越来越熟练。在学Java的同时学习英文，一箭双雕多好。另外好多软件需要到英文网站下载，你要能够找到它们，这些是最基本的要求,英语好对你学习有很大的帮助。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>使用合适的工具工欲善其事必先利其器。软件开发包含各种各样的活动，需求收集分析、建立用例模型、建立分析设计模型、编程实现、调试程序、自动化测试、持续集成等等，没有工具帮忙可以说是寸步难行。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>工具可以提高开发效率，使软件的质量更高BUG更少。组合称手的武器。到飞花摘叶皆可伤人的境界就很高了，无招胜有招，手中无剑心中有剑这样的境界几乎不可企及。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>&lt;span>从软件开发人员的生涯规划来讲，我们可以大致分为三个阶段，软件工程师→软件设计师→架构设计师或项目管理师。&lt;/span>&lt;/span>&lt;span>不想当元帅的士兵不是好士兵，不想当架构设计师或项目管理师的程序员也不是好的程序员。我们应该努力往上走。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>Java是现在大型软件项目中的主角，市场用人需求量大,大家都知道21世纪进入信息时代，信息科技给人类的生产和生活方式带来了深刻的变革，信息产业已成为推动国家经济发展的主导产业之一，为此，从就业前景，发展方向等多方面来看，学Java编程无疑是最佳选择。&lt;/span>&lt;/p>&lt;div>&lt;span>&lt;br>&lt;/span>&lt;/div></description></item><item><title>惹毛程序员的十件事！需求变更居然不是排第一！</title><link>https://pangyd.com/post/176/</link><pubDate>Mon, 20 Nov 2017 18:26:26 +0800</pubDate><guid>https://pangyd.com/post/176/</guid><description>&lt;p>程序员是一个比较特殊的群体，他们因为长期和电脑打交道养成的性格和脾气是比较相近的。当然，既然是人，都会有性格的，也会有脾气的。下面，让我们来看看十件能把程序员惹毛了的事情。&lt;/p>&lt;div class="content rich" data-reactid=".0.1.0.0.0.1.1.1">&lt;p>&lt;span>&lt;span>第十位：程序注释&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;img class="" data-ratio="0.66625" data-src="https://pangyd.com/uploads/2017/11/74c10f869f038762.jpg" data-type="jpeg" data-w="800" height="446.3875" width="670" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-fail="0">&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>程序注释本来是一些比较好的习惯，当程序员老手带新手的时候，总是会告诉新手，一定要写程序注释。于是，新手们当然会听从老手的吩咐。只不过，他们可能对程序注释有些误解，于是，我们经常在程序中看到一些如下的注释：&lt;/span>&lt;/p>&lt;p>&lt;span>每当看到这样的注释——只注释是什么，而不注释为什么，相信你一定会被惹火，这是谁写的程序注释啊？不找来骂一顿看来是不会解气了。程序注释应该是告诉别人你的意图和想法，而不是告诉别人程序的语法，这是为了程序的易读性和可维护性，这样的为了注释而注释的注释，分明不是在注释，而是在挑衅，惹毛别人当然毋庸置疑。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>&lt;span>第九位：打断&lt;/span>&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;img class="" width="670" height="352.5875" data-src="https://pangyd.com/uploads/2017/11/74c10f869f038762.jpg" data-ratio="0.52625" data-w="800" data-type="jpeg" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-fail="0">&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>正当程序沉浸于编程算法的思考，或是灵感突现正在书写程序的时候，但却遭到别人的打断，那是一件非常痛苦的事情，如果被持续打断，那可能会让人一下子就烦躁起来。打断别人的人在这种情况下是非常不礼貌的。被打断的人就像函数调用一下，当其返回时，需要重新恢复断点时的现场。当然，人不是电脑，恢复现场通常是一个很痛苦的过程，极端的情况下可能需要从头开始寻找思绪，然后一点一点地回到断点。&lt;/span>&lt;br>&lt;/p>&lt;p>&lt;span>因此，我看到一些程序员在需要安静不被打扰的时候，要么会选择去一个没人找得到的地方，要么会在自己的桌子上方高挂一个条幅以示众人——「本人正执行内核程序，无法中断，请勿骚扰，谢谢！」自然，被打断所惹毛了的人也不在少数了。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>&lt;span>第八位：需求变化&lt;/span>&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;img class="" width="670" height="446.3875" data-src="https://pangyd.com/uploads/2017/11/74c10f869f038762.jpg" data-ratio="0.66625" data-w="800" data-type="jpeg" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-fail="0">&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>这个事情估计不用多说了。只要是是程序员，面对需求变化的时候可能总是很无奈的。一次两次可能还可以接受，但也顶不住经常变啊。据说敏捷开发中有一套方法论可以让程序员们享受需求的变化，不知道是真是假。不过，今天让你做一个书桌，明天让你把书桌改成餐桌，后天让你把餐桌改成双人床，大后天让你把床改成小木屋，然后把小木屋再改成高楼大厦。哎，是人都会被惹毛了的。那些人只用 30 分钟的会议就可以作出任何决定，但后面那几十个程序员需要搭上几百个小时的辛苦工作。如果是我，可能我也需要神兽草泥马帮助解解气了。&lt;/span>&lt;/p>&lt;p>&lt;span>不过，这也正说明了，程序员并不懂得怎么和用户沟通，而用户也不懂得和程序员沟通，如果一个项目没有一个中间人（如 PM）在其中协调的话，那么整个项目可能就是「鸡同鸭讲」，用户和程序员都会被对方所惹毛了。如果要举例几个用户被惹毛的事情，估计程序员的那种一根筋的只从技术实现上思考问题的方法应该也能排进前 5 名。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>&lt;span>第七位：经理不懂技术&lt;/span>&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;img class="" width="670" height="445.55" data-src="https://pangyd.com/uploads/2017/11/74c10f869f038762.jpg" data-ratio="0.665" data-w="800" data-type="jpeg" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-fail="0">&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>外行领导内行的事例还少吗？领导一句话，无论对不对，都是对的，我们必需照做，哪怕是多么愚蠢多么错误的决定，我们也得照做。程序员其实并不怕经理不懂技术，最怕的就是不懂技术的经理装着很懂技术。最可气的是，当你据理力争的挑战领导权威的时候，领导还把你视为异类。哎，想起这样的领导别说是骂人了，打人的冲动都有了。&lt;/span>&lt;/p>&lt;p>&lt;span>其实，经理只不过是一个团队的支持者，他应该帮助团队，为团队排忧解难。而不是对团队发号施令。其实管理真的很简单，如果懂的话，就帮着做，如果不懂的话，就相信下属，放手让下属做。最怕的就是又不懂技术，还不信任下属的经理了。哎，这真是程序员的痛啊。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>&lt;span>第六位：用户文档&lt;/span>&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;img class="" width="670" height="504.175" data-src="https://pangyd.com/uploads/2017/11/74c10f869f038762.jpg" data-ratio="0.7525" data-w="800" data-type="jpeg" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-fail="0">&lt;/p></description></item><item><title>Java学习笔记--SSH框架整合(struts2、spring4、hibernate5)</title><link>https://pangyd.com/post/175-java-ssh-struts2spring4hibernate5/</link><pubDate>Sun, 19 Nov 2017 19:53:27 +0800</pubDate><guid>https://pangyd.com/post/175-java-ssh-struts2spring4hibernate5/</guid><description>&lt;p style="text-align: center">&lt;span>&lt;span>&lt;strong>一、SSH三大框架的概述&lt;/strong>&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>　&lt;/span>&lt;span>　&lt;/span>&lt;span>&lt;span>ssh为 struts+spring+hibernate的一个&lt;span>&lt;span>集成框架&lt;/span>&lt;/span>，是目前较流行的一种Web应用程序开源框架。&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>　 &amp;nbsp;集成SSH框架的系统从职责上分为四层：&lt;span>&lt;span>&lt;span>表示层&lt;/span>&lt;/span>、&lt;span>&lt;span>业务逻辑层&lt;/span>&lt;/span>、&lt;span>数据持久层&lt;/span>和&lt;span>域模块层（实体层）&lt;/span>&lt;/span>，以帮助开发人员在短期内搭建结构清晰、可复用性好、维护方便的Web应用程序。&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>&lt;span>&lt;span>struts2：&lt;/span>&lt;/span>　　&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>　　　&lt;span>　&lt;span>1、什么是struts2：&lt;/span>&lt;/span>&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>　　　　　　&lt;span>Struts2是一个基于MVC设计模式的Web应用框架，它本质上相当于一个servlet，在MVC设计模式中，Struts2作为控制器(Controller)来建立模型与视图的数据交互。Struts 2是Struts的下一代产品，是在 struts 1和WebWork的技术基础上进行了合并的全新的Struts 2框架。其全新的Struts 2的体系结构与Struts 1的体系结构差别巨大。Struts 2以WebWork为核心，采用拦截器的机制来处理用户的请求，这样的设计也使得业务逻辑控制器能够与ServletAPI完全脱离开，所以Struts 2可以理解为WebWork的更新产品。虽然从Struts 1到Struts 2有着太大的变化，但是相对于WebWork，Struts 2的变化很小。&lt;/span>&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>&lt;span>　　　　&lt;span>2、struts2框架的运行结构：&lt;/span>&lt;/span>&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>&lt;span>&lt;span>&lt;/span>&lt;/span>&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>&lt;span>　　　&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" alt="">&lt;/span>&lt;/span>&lt;/span>&lt;/p>&lt;p>&amp;nbsp;&lt;/p>&lt;p>&lt;span>&lt;span>　　　　&lt;span>解析：&lt;/span>&lt;/span>&lt;/span>&lt;span>客户端发送请求(HttpServletRequest)到服务器，服务器接收到请求就先进入web.xml配置文件看看有没有配置过滤器，发现有struts2的过滤器，然后就找到struts.xml配置文件，struts.xml配置文件里有定义一个action，然后就去找到类名叫IndexAction这个类(此action类必须是继承ActionSupport接口)，并且实现了execute()方法，返回一个字符串为"success"给struts.xml配置文件，struts.xml配置文件的action会默认调用IndexAction类的execute()方法，result接收到了返回的字符串，然后查找结果字符串对应的(Result），result就会调用你指定的jsp页面将结果呈现，最后响应回给客户端。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>　　&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>　&lt;span>&lt;span>　&lt;span>spring：&lt;/span>&lt;/span>&lt;/span>&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>&lt;span>&lt;span>&lt;span>　　　&lt;/span>&lt;/span>&lt;/span>&lt;span>&lt;span>&lt;span>1、什么是spring?&lt;/span>&lt;/span>&lt;/span>&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>&lt;span>&lt;span>&lt;span>　　　　　&lt;span>　Spring是一个轻量级控制反转(IoC)和面向切面(AOP)的容器框架。&lt;/span>&lt;/span>&lt;/span>&lt;/span>&lt;/span>&lt;/span>&lt;span>&lt;span>&lt;span>&lt;span>&lt;span>&lt;span>&lt;span>　&lt;/span>　　　　　　&lt;/span>&lt;/span>&lt;/span>&lt;/span>&lt;/span>&lt;/span>&lt;/p>&lt;div class="para">　　　　　　　　&lt;span>&lt;span>轻量&lt;/span>——从大小与开销两方面而言Spring都是轻量的。完整的Spring框架可以在一个大小只有1MB多的JAR文件里发布。并且Spring所需的处理开销也是微不足道的。此外，Spring是非侵入式的：典型地，Spring应用中的对象不依赖于Spring的特定类。&lt;/span>&amp;nbsp;&lt;/div>&lt;div class="para">&lt;span>　　　　　　　　&lt;span>控制反转&lt;/span>——Spring通过一种称作控制反转（IoC）的技术促进了松耦合。当应用了IoC，一个对象依赖的其它对象会通过被动的方式传递进来，而不是这个对象自己创建或者查找依赖对象。你可以认为IoC与JNDI相反——不是对象从容器中查找依赖，而是容器在对象初始化时不等对象请求就主动将依赖传递给它。&lt;/span>&lt;/div>&lt;div class="para">&lt;span>　　　　　　　&lt;span>&lt;span>　面向切面&lt;/span>&lt;/span>——Spring提供了&lt;span>面向切面编程&lt;/span>的丰富支持，允许通过分离应用的业务逻辑与系统级服务（例如审计（auditing）和事务（transaction）管理）进行内聚性的开发。应用对象只实现它们应该做的——完成业务逻辑——仅此而已。它们并不负责（甚至是意识）其它的系统级关注点，例如日志或事务支持。&lt;/span>&lt;/div>&lt;div class="para">&lt;span>　　　　　　　　&lt;span>容器&lt;/span>——Spring包含并管理应用对象的配置和生命周期，在这个意义上它是一种容器，你可以配置你的每个bean如何被创建——基于一个可配置原型（prototype），你的bean可以创建一个单独的实例或者每次需要时都生成一个新的实例——以及它们是如何相互关联的。然而，Spring不应该被混同于传统的重量级的EJB容器，它们经常是庞大与笨重的，难以使用。&lt;/span>&lt;/div>&lt;div class="para">&lt;span>　　　　　　　　&lt;span>框架&lt;/span>——Spring可以将简单的组件配置、组合成为复杂的应用。在Spring中，应用对象被声明式地组合，典型地是在一个XML文件里。Spring也提供了很多基础功能（事务管理、持久化框架集成等等），将应用逻辑的开发留给了你。&lt;/span>&lt;/div>&lt;p>&amp;nbsp;&lt;/p>&lt;p>&lt;span>&lt;span>　　&lt;span>　　2、spring的流程图：&lt;/span>&lt;/span>&lt;/span>&lt;span>&lt;span>　&lt;/span>　&lt;/span>&lt;span>&lt;span>　　&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" alt="">&lt;/span>&lt;/span>&lt;/p>&lt;p>　　　&lt;span>　解析：&lt;/span>&lt;span>&lt;span>上图是在struts结构图的基础上加入了spring流程图，在web.xml配置文件中加入了spring的监听器，在struts.xml配置文件中添加“&lt;/span>&lt;span>&amp;lt;constant name="struts.objectFactory" value="spring" /&amp;gt;&lt;/span>&lt;span>”是告知Struts2运行时使用Spring来创建对象，spring在其中主要做的就是注入实例，将所有需要类的实例都由spring管理。&lt;/span>&lt;/span>&lt;/p>&lt;p>&amp;nbsp;&lt;/p>&lt;p>&lt;span>　　&lt;span>&lt;span>hibernate：&lt;/span>&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>&lt;span>　　　&lt;/span>&lt;span>1、什么是hibernate？&lt;/span>&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>&lt;span>　　　&lt;/span>&lt;span>　Hibernate是一个开放源代码的对象关系映射框架，它对JDBC进行了非常轻量级的对象封装，它将POJO与数据库表建立映射关系，是一个全自动的orm框架，hibernate可以自动生成SQL语句，自动执行，使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合，既可以在Java的客户端程序使用，也可以在Servlet/JSP的Web应用中使用，最具革命意义的是，Hibernate可以在应用EJB的J2EE架构中取代CMP，完成数据持久化的重任。&lt;/span>&lt;/span>&lt;/span>&lt;/p></description></item><item><title>【SSH网上商城项目实战30】项目总结（附源码下载地址）</title><link>https://pangyd.com/post/174-ssh30/</link><pubDate>Sun, 19 Nov 2017 19:52:46 +0800</pubDate><guid>https://pangyd.com/post/174-ssh30/</guid><description>&lt;table class="layui-table">&lt;tbody>&lt;tr>&lt;td bgcolor="#F5FFFA">&lt;h2 id="0-写在前面">&lt;strong>0. 写在前面&lt;/strong>&lt;/h2>&lt;/td>&lt;/tr>&lt;/tbody>&lt;/table>&lt;p>　　友情提示：点击&amp;gt;&amp;gt;&lt;a href="https://blog.csdn.net/eson_15/article/details/51479994#download" target="_blank">下载地址&lt;/a>&amp;lt;&amp;lt;下载源码。&amp;nbsp;&lt;br>　　项目基本完成了，加上这个总结，与这个项目相关的博客也写了30篇了，积少成多，写博客的过程是固化思路的一个过程，对自己很有用，同时也能帮助别人。顺便说个题外话，在学习的过程中肯定会遇到很多异常出现，我们要做的首先是定位这个异常，一般异常的后面都会跟一个或多个Caused by：xxx，这些都是引起异常的原因，一般我们找最下面的一个Caused by，那里往往才是问题的根源。如果自己解决不了，可以去谷歌、百度搜索（搜索的时候别一大堆异常往上一贴，注意搜关键的部分！），一般我们遇到的问题，99.9%前人都遇到过，基本都能解决，我遇到不能解决的问题基本都是这么干的，自己解决的多了，就有感觉了~最后希望大家在阅读我的博客时会有所收获！　　&amp;nbsp;&lt;br>　　废话就不说了，下面总结一下这个网上商城的项目，我不会面面俱到，主要分为几个模块来总结，包括 用到了哪些技术等等，具体的细节我会在文章中附上快速链接，大家可以查看具体的某篇博文。&amp;nbsp;&lt;br>　　回忆一下这个项目，总共可以分为这些主要的模块：&lt;/p>&lt;blockquote>&lt;ul>&lt;li>&lt;strong>项目环境的搭建&lt;/strong>&lt;/li>&lt;li>&lt;strong>搭建后台管理系统&lt;/strong>&lt;/li>&lt;li>&lt;strong>搭建前台显示页面&lt;/strong>&lt;/li>&lt;li>&lt;strong>购物车相关功能&lt;/strong>&lt;/li>&lt;li>&lt;strong>在线支付功能&lt;/strong>&lt;/li>&lt;li>&lt;strong>邮件和短信的发送功能&lt;/strong>&lt;/li>&lt;li>&lt;strong>域名的申请和项目的部署&lt;/strong>&lt;/li>&lt;li>&lt;strong>表单验证和报表的显示&lt;/strong>&lt;/li>&lt;/ul>&lt;/blockquote>&lt;p>　　下面针对每个模块，做一下具体的分析。&lt;/p>&lt;table class="layui-table">&lt;tbody>&lt;tr>&lt;td bgcolor="#F5FFFA">&lt;h2 id="1-项目环境的搭建">&lt;a name="t1">&lt;/a>&lt;strong>1. 项目环境的搭建&lt;/strong>&lt;/h2>&lt;/td>&lt;/tr>&lt;/tbody>&lt;/table>&lt;p>　　这是每个工程都少不了的环节，而且也会出现很多乱七八糟的问题，刚开始学SSH的时候，总是苦于搭建环境，因为不太熟练，但是熟练了就好了，主要是要“有节奏的”去搭建，也就是说搭建一个环境工程得一步步来，一点点的搭，很多人上来就把jar包啪叽一下全导进去了，然后什么配置文件啊啪叽一下全写好或者从其他地方粘贴来，然后一运行，挂了……然后各种去找问题，何苦呢？这样的话就算搭建10次也不能得心应手。饭要一口口的吃，路要一步一步的走。&amp;nbsp;&lt;br>　　&amp;nbsp;&lt;br>　　SSH的环境搭建，我个人遵循的流程是：&lt;/p>&lt;blockquote>&lt;p>Spring –&amp;gt; Hibernate –&amp;gt; Spring整合Hibernate –&amp;gt; Struts2 –&amp;gt; Spring整合Struts2&lt;/p>&lt;/blockquote>&lt;p>　　每一步做完写个测试类测试一下，这很重要，因为一步步往下走的话，出错了也知道错在哪一步，去哪找问题，最重要的是，这种流程熟练了，下次再搭环境的时候就易如反掌了。关于SSH环境搭建的详细信息请看下面的博文：&amp;nbsp;&lt;br>　　&amp;nbsp;&lt;br>　　&lt;a href="https://blog.csdn.net/eson_15/article/details/51277324" target="&amp;quot;blank">整合Struts2、Hibernate4.3和Spring4.2&lt;/a>&amp;nbsp;&lt;br>　　&lt;a href="https://blog.csdn.net/eson_15/article/details/51297698" target="&amp;quot;blank">基本增删查改、Service和Action的抽取以及使用注解替换xml&lt;/a>&lt;/p>&lt;table class="layui-table">&lt;tbody>&lt;tr>&lt;td bgcolor="#F5FFFA">&lt;h2 id="2-搭建后台管理系统">&lt;a name="t2">&lt;/a>&lt;strong>2. 搭建后台管理系统&lt;/strong>&lt;/h2>&lt;/td>&lt;/tr>&lt;/tbody>&lt;/table>&lt;p>　　后台管理系统我用的是EasyUI搭建的，说真的，EasyUI我也是一知半解，前端的东西我了解的都不深，但是懂一点，具体用的时候也是各种去查的，也没系统的学过，所以没有一个良好的知识体系，但是也不影响去玩。程序猿都喜欢说玩一个技术啥的，听起来好像挺高大上的，慢慢的我也受到一些影响，也喜欢这么说了，不过我对于前端就真的在玩了……　　&amp;nbsp;&lt;br>　　jQuery EasyUI是一组基于jQuery的UI插件集合体，而jQuery EasyUI的目标就是帮助web开发者更轻松的打造出功能丰富并且美观的UI界面。开发者不需要编写复杂的javascript，也不需要对css样式有深入的了解，开发者需要了解的只有一些简单的html标签。　　&amp;nbsp;&lt;br>　　EasyUI的请求都是Ajax请求，不会有新的页面出来，全都都在tab选项卡中或者弹出一个窗口之类的。后台管理系统主要分为三部分：商品的类别管理、商品的管理以及销售管理。销售管理放在最后再说。&lt;/p>&lt;h3 id="21-商品类别的管理">&lt;a name="t3">&lt;/a>&lt;strong>2.1 商品类别的管理&lt;/strong>&lt;/h3>&lt;p>　　该部分主要涉及到了&lt;strong>EasyUI环境和后台框架的搭建&lt;/strong>、&lt;strong>数据库的级联查询和分页&lt;/strong>、&lt;strong>DataGrid数据显示&lt;/strong>、&lt;strong>Struts2整合json&lt;/strong>以及&lt;strong>商品类别的添加、删除、更新和搜索&lt;/strong>。这也是遵循了该部分的一个完成的顺序。　　&amp;nbsp;&lt;br>　　DataGrid以表格的形式展示数据，开发人员不需要具备特定的知识就可以操作它，它有个很好的帮助文档，比较详细，在本项目中我也介绍了创建DataGrid的几种方式，并且也简单介绍了一下DataGrid的部分属性，算是入门吧，我也是入门，多多开发才能掌握这个技术。　　&amp;nbsp;&lt;br>　　类别的添加、删除、更新和搜索功能，主要都是利用EasyUI自带的验证功能，添加商品类别的时，验证输入框的输入是否正确，是否必填等；删除时是否先选中的某一行或某几行；更新的时候每次只能更新一行等，所有这些都是Ajax请求。　　&amp;nbsp;&lt;br>　　关于这部分内容的详细信息，我已经归类了，请参考这些博文：&amp;nbsp;&lt;br>　　&amp;nbsp;&lt;br>　　&lt;a href="https://blog.csdn.net/eson_15/article/details/51312490" target="&amp;quot;blank">使用EasyUI搭建后台页面框架&lt;/a>&amp;nbsp;&lt;br>　　&lt;a href="https://blog.csdn.net/eson_15/article/details/51297705" target="&amp;quot;blank">EasyUI菜单的实现&lt;/a>&amp;nbsp;&lt;br>　　&lt;a href="https://blog.csdn.net/eson_15/article/details/51320212" target="&amp;quot;blank">数据库的级联查询和分页&lt;/a>&amp;nbsp;&lt;br>　　&lt;a href="https://blog.csdn.net/eson_15/article/details/51322262" target="&amp;quot;blank">基于DataGrid的数据显示功能&lt;/a>&amp;nbsp;&lt;br>　　&lt;a href="https://blog.csdn.net/eson_15/article/details/51332758" target="&amp;quot;blank">Struts2和Json的整合&lt;/a>　　&amp;nbsp;&lt;br>　　&lt;a href="https://blog.csdn.net/eson_15/article/details/51338991" target="&amp;quot;blank">DataGrid实现查询和删除功能&lt;/a>&amp;nbsp;&lt;br>　　&lt;a href="https://blog.csdn.net/eson_15/article/details/51347734" target="&amp;quot;blank">DataGrid实现添加和更新功能&lt;/a>&amp;nbsp;&lt;br>　　　　&amp;nbsp;&lt;br>　　下面是我自己遇到的问题：&amp;nbsp;&lt;br>　　&lt;a href="https://blog.csdn.net/eson_15/article/details/51394302" target="&amp;quot;blank">Struts2和Json整合中的懒加载异常问题&lt;/a>&amp;nbsp;&lt;br>　　&lt;a href="https://blog.csdn.net/eson_15/article/details/51383298" target="&amp;quot;blank">Hibernate4执行save()或update()无效&lt;/a>　　&lt;/p>&lt;h3 id="22-商品的管理">&lt;a name="t4">&lt;/a>&lt;strong>2.2 商品的管理&lt;/strong>&lt;/h3>&lt;p>　　商品的管理也有添加删除等操作，跟类别管理道理上是一样的，有个地方就是商品的添加，需要上传商品的照片，这里涉及到了&lt;strong>Struts2实现文件上传&lt;/strong>的功能，我们需要在服务器端建一个文件夹专门用来存储上传文件的，然后写一个model来接收文件，关于文件上传，要专门写一个工具类，项目中开发就是这样的，共性的代码一定要抽取，哪怕只有一句代码也要抽取！这是习惯，也是必须要做的。具体细节参下面列出的这些的博文：&amp;nbsp;&lt;br>　　&amp;nbsp;&lt;br>　　&lt;a href="https://blog.csdn.net/eson_15/article/details/51354932" target="&amp;quot;blank">商品类基本模块的搭建&lt;/a>　　&amp;nbsp;&lt;br>　　&lt;a href="https://blog.csdn.net/eson_15/article/details/51360804" target="&amp;quot;blank">查询和删除商品功能的实现&lt;/a>　　&amp;nbsp;&lt;br>　　&lt;a href="https://blog.csdn.net/eson_15/article/details/51366370" target="&amp;quot;blank">添加和更新商品功能的实现&lt;/a>　　&amp;nbsp;&lt;br>　　&lt;a href="https://blog.csdn.net/eson_15/article/details/51366384" target="&amp;quot;blank">Struts2实现文件上传功能&lt;/a>　　&lt;/p>&lt;table class="layui-table">&lt;tbody>&lt;tr>&lt;td bgcolor="#F5FFFA">&lt;h2 id="3-搭建前台显示页面">&lt;a name="t5">&lt;/a>&lt;strong>3. 搭建前台显示页面&lt;/strong>&lt;/h2>&lt;/td>&lt;/tr>&lt;/tbody>&lt;/table>&lt;p>　　当然，前台的页面不是我设计的，这一块内容我总结的是跟前台显示相关的一些后台技术，比如：&lt;strong>监听器获取首页数据&lt;/strong>、&lt;strong>定时器同步首页数据&lt;/strong>、&lt;strong>Hibernate二级缓存处理热门商品的缓存&lt;/strong>等。&amp;nbsp;&lt;br>　　以前在学习serlvet的时候，首页显示数据我是这么干的，用一个frame，右边显示数据，那么index.jsp中右边的部分我跳转到一个servlet，然后servlet中去数据库中取出所有商品，放到request域中带过去新的jsp页面显示。这虽然能实现，但是很笨。在这里我用了监听器来干这件事，首先自己定义一个监听器，在项目启动的时候把数据库中所有商品信息给取出来，放到application域中，然后首页中直接用EL表达式从application域中去取即可。　　&amp;nbsp;&lt;br>　　还有个问题，当我在管理系统中添加一个新的商品时，我必须要重启一下tomcat才能将新的商品加到application域中，因为第一次取出来后就一直在application域中了，就定死了，后面新添加的就不在application域里面，为了解决这个问题，我使用了定时器来同步首页数据。于是改写了之前写好的监听器，在监听器中设置一个定时器，获取数据库中商品的数据的代码放到定时器任务中，第一次开启立马执行，然后每6个小时执行一次（时间可以自己随便设定），也就是说每6个小时重新获取一下数据库中的商品，存到application域中。一般网站也是这么干的，像CSDN的个人博客主页也是，每天更新一次排名，大概是晚上10点左右吧，具体时间我忘了。那个时候刷新就会看到数据的更新，这样也减小了服务器的压力。&lt;/p>&lt;p>　　该部分具体的技术细节，参见下面这几篇博文：&amp;nbsp;&lt;br>　　&amp;nbsp;&lt;br>　　&lt;a href="https://blog.csdn.net/eson_15/article/details/51373403" target="&amp;quot;blank">使用监听器获取显示在首页的数据&lt;/a>　　&amp;nbsp;&lt;br>　　&lt;a href="https://blog.csdn.net/eson_15/article/details/51373937" target="&amp;quot;blank">监听器如何获取Spring的配置文件&lt;/a>　&amp;nbsp;&lt;br>　　&lt;a href="https://blog.csdn.net/eson_15/article/details/51387378" target="&amp;quot;blank">线程、定时器定时同步首页数据&lt;/a>　&amp;nbsp;&lt;br>　　&lt;a href="https://blog.csdn.net/eson_15/article/details/51405911" target="&amp;quot;blank">Hibernate二级缓存处理首页的热门显示&lt;/a>&lt;/p>&lt;table class="layui-table">&lt;tbody>&lt;tr>&lt;td bgcolor="#F5FFFA">&lt;h2 id="4-购物车相关功能">&lt;a name="t6">&lt;/a>&lt;strong>4. 购物车相关功能&lt;/strong>&lt;/h2>&lt;/td>&lt;/tr>&lt;/tbody>&lt;/table>&lt;p>　　购物车的部分主要涉及到的技术有：&lt;strong>后台的处理购物车和购物项的逻辑&lt;/strong>、&lt;strong>过滤器判断登陆&lt;/strong>、&lt;strong>订单的级联入库&lt;/strong>以及&lt;strong>页面缓存&lt;/strong>的问题。&amp;nbsp;&lt;br>　　购物车的话主要是后台的一些实现逻辑了，购物车里需要有购物项，啥意思呢？我们在天猫上买东西都知道，可以把不同的商品都放到购物车里，然后购物车里有很多商品，每个商品的数量又可以有多个，每个商品及其相关信息就是一个购物项，所以添加购物车的时候，我们首先要完成一个购物项，再将此购物项添加到购物车里。&amp;nbsp;&lt;br>　　当用户想要结算的时候，我们得首先判断用户有没有登陆，这用到了过滤器技术，专门过滤某一类的url，在过滤器中判断当前session中有没有user对象，如果有说明登陆过了，直接放行就行，如果没有则跳转到登陆页面让用户登陆，登陆完成后跳转到用户原来想去的页面。也就相当于门卫一样~看大门的~&amp;nbsp;&lt;br>　　刚刚也提到了，订单信息包含 购物车和购物项，那么我们在订单入库的时候，就要考虑到它们的级联问题，我们可以通过在两者的POJO中设置相应的注解属性即可，但是有个前提，像这种有外键关联的，在入库之前都要将对应的POJO中的外键部分的字段赋好值，比如订单要将订单项加进去，订单项中的订单属性也得赋好值，然后才可以交给Hibernate，Hibernate根据配置好的注解（或者xml文件）将它们一起级联入库。&amp;nbsp;&lt;br>　　页面缓存的问题指的是，当用户确认了订单后，如果点后退，又会回到订单确认页面，刚刚的订单确认页面又出来了，而且session还在，信息还是刚刚的信息，这明显不是我们想要的结果。我们需要在前台和后台同时进行处理才行。&amp;nbsp;&lt;br>　　该部分具体技术细节，请参见下面的几篇博文：&lt;/p></description></item><item><title>SSH框架整合demo</title><link>https://pangyd.com/post/173-sshdemo/</link><pubDate>Sun, 19 Nov 2017 19:49:15 +0800</pubDate><guid>https://pangyd.com/post/173-sshdemo/</guid><description>&lt;h1>Struts、Spring、Hibernate整合&lt;/h1>&lt;h2>&lt;a name="t1">&lt;/a>一、创建web工程，搭建Struts框架开发环境：&lt;/h2>&lt;div>这里只导入了项目中所需要的重要的jar包，以后根据业务要求继续导入相关的包。&lt;br>&lt;/div>&lt;div>&lt;ol>&lt;li>步骤1：:导入struts框架所需的jar包&lt;/li>&lt;li>步骤2：在web.xml中配置struts2.0主过滤器&lt;/li>&lt;li>步骤3：导入struts.xml配置文件&lt;/li>&lt;/ol>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" alt="">&lt;br>&lt;/div>&lt;div>web.xml&lt;/div>&lt;div>&lt;div class="dp-highlighter bg_html">&lt;div class="bar">&lt;div class="tools">&lt;b>[html]&lt;/b>&amp;nbsp;&lt;a href="https://blog.csdn.net/btt2013/article/details/51051660#" class="ViewSource" title="view plain">view plain&lt;/a>&lt;span class="tracking-ad" data-mod="popu_168">&amp;nbsp;&lt;a href="https://blog.csdn.net/btt2013/article/details/51051660#" class="CopyToClipboard" title="copy">copy&lt;/a>&lt;div>&lt;/div>&lt;/span>&lt;span class="tracking-ad" data-mod="popu_169">&lt;/span>&lt;/div>&lt;/div>&lt;ol start="1" class="dp-xml">&lt;li class="alt">&lt;span>&lt;span class="tag">&amp;lt;?&lt;/span>&lt;span class="tag-name">xml&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">version&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"1.0"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">encoding&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"UTF-8"&lt;/span>&lt;span class="tag">?&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">web-app&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">version&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"2.5"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">xmlns&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"https://java.sun.com/xml/ns/javaee"&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="attribute">xmlns:xsi&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"https://www.w3.org/2001/XMLSchema-instance"&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="attribute">xsi:schemaLocation&lt;/span>&lt;span>="https://java.sun.com/xml/ns/javaee&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comments">&amp;lt;!--&amp;nbsp;&amp;nbsp;配置Struts2的主过滤器&amp;nbsp;--&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">filter&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">filter-name&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>struts2&lt;/span>&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">filter-name&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">filter-class&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter&lt;/span>&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">filter-class&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">filter&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">filter-mapping&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">filter-name&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>struts2&lt;/span>&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">filter-name&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">url-pattern&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>/*&lt;/span>&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">url-pattern&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">filter-mapping&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">welcome-file-list&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">welcome-file&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>index.jsp&lt;/span>&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">welcome-file&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">welcome-file-list&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">web-app&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;/ol>&lt;/div>struts.xml&lt;/div>&lt;div>&lt;div class="dp-highlighter bg_html">&lt;div class="bar">&lt;div class="tools">&lt;b>[html]&lt;/b>&amp;nbsp;&lt;a href="https://blog.csdn.net/btt2013/article/details/51051660#" class="ViewSource" title="view plain">view plain&lt;/a>&lt;span class="tracking-ad" data-mod="popu_168">&amp;nbsp;&lt;a href="https://blog.csdn.net/btt2013/article/details/51051660#" class="CopyToClipboard" title="copy">copy&lt;/a>&lt;div>&lt;/div>&lt;/span>&lt;span class="tracking-ad" data-mod="popu_169">&lt;/span>&lt;/div>&lt;/div>&lt;ol start="1" class="dp-xml">&lt;li class="alt">&lt;span>&lt;span class="tag">&amp;lt;?&lt;/span>&lt;span class="tag-name">xml&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">version&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"1.0"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">encoding&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"UTF-8"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="tag">?&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;lt;!DOCTYPE&amp;nbsp;struts&amp;nbsp;PUBLIC&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"-//Apache&amp;nbsp;Software&amp;nbsp;Foundation//DTD&amp;nbsp;Struts&amp;nbsp;Configuration&amp;nbsp;2.3//EN"&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"https://struts.apache.org/dtds/struts-2.3.dtd"&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="">&lt;span>&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">struts&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comments">&amp;lt;!--&amp;nbsp;配置为开发模式&amp;nbsp;--&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">constant&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">name&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"struts.devMode"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">value&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"true"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="tag">/&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comments">&amp;lt;!--&amp;nbsp;配置扩展名为action&amp;nbsp;--&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">constant&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">name&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"struts.action.extension"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">value&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"action"&lt;/span>&lt;span class="tag">/&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">package&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">name&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"default"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">namespace&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"/"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">extends&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"struts-default"&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">package&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">struts&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;/ol>&lt;/div>&lt;/div>&lt;h2>&lt;a name="t2">&lt;/a>二、搭建Hibernate开发环境：&lt;/h2>&lt;div>创建数据库：&lt;/div>&lt;div>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" alt="">&lt;br>&lt;/div>&lt;div>这里只导入了项目中所需要的重要的jar包，以后根据业务要求继续导入相关的包。&lt;br>&lt;/div>&lt;div>工程目录：&lt;/div>&lt;div>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" alt="">&lt;br>&lt;/div>&lt;div>hibernate.cfg.xml&lt;br>&lt;/div>&lt;div>&lt;div class="dp-highlighter bg_html">&lt;div class="bar">&lt;div class="tools">&lt;b>[html]&lt;/b>&amp;nbsp;&lt;a href="https://blog.csdn.net/btt2013/article/details/51051660#" class="ViewSource" title="view plain">view plain&lt;/a>&lt;span class="tracking-ad" data-mod="popu_168">&amp;nbsp;&lt;a href="https://blog.csdn.net/btt2013/article/details/51051660#" class="CopyToClipboard" title="copy">copy&lt;/a>&lt;div>&lt;/div>&lt;/span>&lt;span class="tracking-ad" data-mod="popu_169">&lt;/span>&lt;/div>&lt;/div>&lt;ol start="1" class="dp-xml">&lt;li class="alt">&lt;span>&lt;span class="tag">&amp;lt;?&lt;/span>&lt;span class="tag-name">xml&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">version&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"1.0"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">encoding&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"UTF-8"&lt;/span>&lt;span class="tag">?&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;lt;!DOCTYPE&amp;nbsp;hibernate-configuration&amp;nbsp;PUBLIC&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"-//Hibernate/Hibernate&amp;nbsp;Configuration&amp;nbsp;DTD&amp;nbsp;3.0//EN"&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"https://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">hibernate-configuration&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">session-factory&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comments">&amp;lt;!--&amp;nbsp;配置Hibernate:属性配置参考&amp;nbsp;&amp;nbsp;Hibernate发型包\project\etc\hibernate.properties&amp;nbsp;--&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comments">&amp;lt;!--&amp;nbsp;JDBC的基本链接&amp;nbsp;--&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">name&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"hibernate.connection.driver_class"&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>com.mysql.jdbc.Driver&lt;/span>&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">name&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"connection.username"&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>root&lt;/span>&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">name&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"connection.password"&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>root&lt;/span>&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">name&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"connection.url"&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>jdbc:mysql://localhost:3306/xbmuoa&lt;/span>&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comments">&amp;lt;!--&amp;nbsp;配置数据库方言&amp;nbsp;--&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">name&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"dialect"&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>org.hibernate.dialect.MySQLDialect&lt;/span>&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;!--&amp;nbsp;根据映射产生表结构的类型:&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;create-drop:木有表结构创建，下次启动时删除重新创建。适合学习阶段&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;create：只做创建&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;update：探测表结构够的变化，对于数据库没有的，进行更新操作。适合学习阶段&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;validate：对比与数据库的结构&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;--&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">name&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"hibernate.hbm2ddl.auto"&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>update&lt;/span>&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comments">&amp;lt;!--&amp;nbsp;显示sql语句及格式：开发调试阶段非常有用&amp;nbsp;--&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">name&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"hibernate.show_sql"&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>true&lt;/span>&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">name&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"hibernate.format_sql"&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>true&lt;/span>&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comments">&amp;lt;!--&amp;nbsp;告知映射文件&amp;nbsp;--&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">session-factory&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">hibernate-configuration&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;/ol>&lt;/div>Person.hbm.xml（暂时性先写个映射文件的模板）&lt;/div>&lt;div>&lt;div class="dp-highlighter bg_html">&lt;div class="bar">&lt;div class="tools">&lt;b>[html]&lt;/b>&amp;nbsp;&lt;a href="https://blog.csdn.net/btt2013/article/details/51051660#" class="ViewSource" title="view plain">view plain&lt;/a>&lt;span class="tracking-ad" data-mod="popu_168">&amp;nbsp;&lt;a href="https://blog.csdn.net/btt2013/article/details/51051660#" class="CopyToClipboard" title="copy">copy&lt;/a>&lt;div>&lt;/div>&lt;/span>&lt;span class="tracking-ad" data-mod="popu_169">&lt;/span>&lt;/div>&lt;/div>&lt;ol start="1" class="dp-xml">&lt;li class="alt">&lt;span>&lt;span class="tag">&amp;lt;?&lt;/span>&lt;span class="tag-name">xml&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">version&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"1.0"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">encoding&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"UTF-8"&lt;/span>&lt;span class="tag">?&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;lt;!DOCTYPE&amp;nbsp;hibernate-mapping&amp;nbsp;PUBLIC&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"-//Hibernate/Hibernate&amp;nbsp;Mapping&amp;nbsp;DTD&amp;nbsp;3.0//EN"&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"https://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">hibernate-mapping&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">package&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"cn.xbmu.oa.domain"&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">hibernate-mapping&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;/ol>&lt;/div>&lt;/div>&lt;h2>&lt;a name="t3">&lt;/a>三、搭建Spring开发环境：&lt;/h2>&lt;div>这里只导入了项目中所需要的重要的jar包，以后根据业务要求继续导入相关的包。&lt;/div>&lt;div>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" alt="">&lt;br>&lt;/div>&lt;div>applicationContext.xml&lt;br>&lt;/div>&lt;div>&lt;div class="dp-highlighter bg_html">&lt;div class="bar">&lt;div class="tools">&lt;b>[html]&lt;/b>&amp;nbsp;&lt;a href="https://blog.csdn.net/btt2013/article/details/51051660#" class="ViewSource" title="view plain">view plain&lt;/a>&lt;span class="tracking-ad" data-mod="popu_168">&amp;nbsp;&lt;a href="https://blog.csdn.net/btt2013/article/details/51051660#" class="CopyToClipboard" title="copy">copy&lt;/a>&lt;div>&lt;/div>&lt;/span>&lt;span class="tracking-ad" data-mod="popu_169">&lt;/span>&lt;/div>&lt;/div>&lt;ol start="1" class="dp-xml">&lt;li class="alt">&lt;span>&lt;span class="tag">&amp;lt;?&lt;/span>&lt;span class="tag-name">xml&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">version&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"1.0"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">encoding&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"UTF-8"&lt;/span>&lt;span class="tag">?&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">beans&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">xmlns&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"https://www.springframework.org/schema/beans"&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="attribute">xmlns:xsi&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"https://www.w3.org/2001/XMLSchema-instance"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">xmlns:context&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"https://www.springframework.org/schema/context"&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="attribute">xmlns:tx&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"https://www.springframework.org/schema/tx"&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="attribute">xsi:schemaLocation&lt;/span>&lt;span>="https://www.springframework.org/schema/beans&amp;nbsp;http://www.springframework.org/schema/beans/spring-beans-2.5.xsd&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;https://www.springframework.org/schema/context&amp;nbsp;http://www.springframework.org/schema/context/spring-context-2.5.xsd&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;https://www.springframework.org/schema/tx&amp;nbsp;http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comments">&amp;lt;!--&amp;nbsp;自动扫描与装配bean&amp;nbsp;--&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">context:component-scan&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">base-package&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"cn.xbmu.oa"&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">context:component-scan&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">beans&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;/ol>&lt;/div>&lt;strong>以上已经将Struts、Spring、Hibernate开发所需要的jar包及其配置文件已经配置到web工程中了。&lt;/strong>&lt;/div>&lt;div>&lt;strong>接下来，我们两两整合在一起。&lt;br>&lt;/strong>&lt;h2>&lt;a name="t4">&lt;/a>四、Spring与Hibernate整合：&lt;/h2>&lt;/div>&lt;div>&lt;span>让Spring来管理SessionFactory和事务。&lt;/span>&lt;/div>&lt;div>工程目录：&lt;/div>&lt;div>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" alt="">&lt;br>&lt;/div>&lt;div>applicationContext.xml&lt;/div>&lt;div>&lt;div class="dp-highlighter bg_html">&lt;div class="bar">&lt;div class="tools">&lt;b>[html]&lt;/b>&amp;nbsp;&lt;a href="https://blog.csdn.net/btt2013/article/details/51051660#" class="ViewSource" title="view plain">view plain&lt;/a>&lt;span class="tracking-ad" data-mod="popu_168">&amp;nbsp;&lt;a href="https://blog.csdn.net/btt2013/article/details/51051660#" class="CopyToClipboard" title="copy">copy&lt;/a>&lt;div>&lt;/div>&lt;/span>&lt;span class="tracking-ad" data-mod="popu_169">&lt;/span>&lt;/div>&lt;/div>&lt;ol start="1" class="dp-xml">&lt;li class="alt">&lt;span>&lt;span class="tag">&amp;lt;?&lt;/span>&lt;span class="tag-name">xml&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">version&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"1.0"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">encoding&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"UTF-8"&lt;/span>&lt;span class="tag">?&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">beans&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">xmlns&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"https://www.springframework.org/schema/beans"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">xmlns:xsi&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"https://www.w3.org/2001/XMLSchema-instance"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">xmlns:context&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"https://www.springframework.org/schema/context"&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="attribute">xmlns:tx&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"https://www.springframework.org/schema/tx"&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="attribute">xsi:schemaLocation&lt;/span>&lt;span>="https://www.springframework.org/schema/beans&amp;nbsp;http://www.springframework.org/schema/beans/spring-beans-2.5.xsd&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;https://www.springframework.org/schema/context&amp;nbsp;http://www.springframework.org/schema/context/spring-context-2.5.xsd&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;https://www.springframework.org/schema/tx&amp;nbsp;http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comments">&amp;lt;!--&amp;nbsp;自动扫描与装配bean&amp;nbsp;--&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">context:component-scan&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">base-package&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"cn.xbmu.oa"&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">context:component-scan&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comments">&amp;lt;!--&amp;nbsp;加载外部的properties配置文件&amp;nbsp;--&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">context:property-placeholder&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">location&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"classpath:jdbc.properties"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="tag">/&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comments">&amp;lt;!--&amp;nbsp;配置数据库连接池（c3p0）&amp;nbsp;--&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">bean&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">id&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"dataSource"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">class&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"com.mchange.v2.c3p0.ComboPooledDataSource"&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comments">&amp;lt;!--&amp;nbsp;基本信息&amp;nbsp;--&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">name&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"jdbcUrl"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">value&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"${jdbcUrl}"&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">name&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"driverClass"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">value&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"${driverClass}"&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">name&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"user"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">value&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"${username}"&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">name&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"password"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">value&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"${password}"&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comments">&amp;lt;!--&amp;nbsp;其他配置&amp;nbsp;--&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comments">&amp;lt;!--初始化时获取三个连接，取值应在minPoolSize与maxPoolSize之间。Default:&amp;nbsp;3&amp;nbsp;--&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">name&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"initialPoolSize"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">value&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"3"&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comments">&amp;lt;!--连接池中保留的最小连接数。Default:&amp;nbsp;3&amp;nbsp;--&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">name&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"minPoolSize"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">value&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"3"&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comments">&amp;lt;!--连接池中保留的最大连接数。Default:&amp;nbsp;15&amp;nbsp;--&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">name&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"maxPoolSize"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">value&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"5"&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comments">&amp;lt;!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default:&amp;nbsp;3&amp;nbsp;--&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">name&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"acquireIncrement"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">value&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"3"&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comments">&amp;lt;!--&amp;nbsp;控制数据源内加载的PreparedStatements数量。如果maxStatements与maxStatementsPerConnection均为0，则缓存被关闭。Default:&amp;nbsp;0&amp;nbsp;--&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">name&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"maxStatements"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">value&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"8"&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comments">&amp;lt;!--&amp;nbsp;maxStatementsPerConnection定义了连接池内单个连接所拥有的最大缓存statements数。Default:&amp;nbsp;0&amp;nbsp;--&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">name&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"maxStatementsPerConnection"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">value&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"5"&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comments">&amp;lt;!--最大空闲时间,1800秒内未使用则连接被丢弃。若为0则永不丢弃。Default:&amp;nbsp;0&amp;nbsp;--&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">name&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"maxIdleTime"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">value&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"1800"&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">bean&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comments">&amp;lt;!--&amp;nbsp;配置SessionFactory&amp;nbsp;--&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">bean&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">id&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"sessionFactory"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">class&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"org.springframework.orm.hibernate3.LocalSessionFactoryBean"&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">name&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"dataSource"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">ref&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"dataSource"&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">name&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"configLocation"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">value&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"classpath:hibernate.cfg.xml"&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">bean&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comments">&amp;lt;!--&amp;nbsp;配置声明式的事务管理（采用基于注解的方式）&amp;nbsp;--&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">bean&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">id&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"transactionManager"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">class&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"org.springframework.orm.hibernate3.HibernateTransactionManager"&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">name&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"sessionFactory"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">ref&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"sessionFactory"&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">bean&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">tx:annotation-driven&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">transaction-manager&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"transactionManager"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="tag">/&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="">&lt;span>&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">beans&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;/ol>&lt;/div>&lt;/div>&lt;div>&lt;pre>&lt;/pre>jdbc.properties&lt;/div>&lt;div>&lt;div class="dp-highlighter bg_plain">&lt;div class="bar">&lt;div class="tools">&lt;b>[plain]&lt;/b>&amp;nbsp;&lt;a href="https://blog.csdn.net/btt2013/article/details/51051660#" class="ViewSource" title="view plain">view plain&lt;/a>&lt;span class="tracking-ad" data-mod="popu_168">&amp;nbsp;&lt;a href="https://blog.csdn.net/btt2013/article/details/51051660#" class="CopyToClipboard" title="copy">copy&lt;/a>&lt;div>&lt;/div>&lt;/span>&lt;span class="tracking-ad" data-mod="popu_169">&lt;/span>&lt;/div>&lt;/div>&lt;ol start="1">&lt;li class="alt">&lt;span>&lt;span>jdbcUrl&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;=&amp;nbsp;jdbc:mysql:///xbmuoa&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>driverClass&amp;nbsp;=&amp;nbsp;com.mysql.jdbc.Driver&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>username&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;=&amp;nbsp;root&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="">&lt;span>password&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;=&amp;nbsp;root&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;/ol>&lt;/div>SpringTest.java&lt;/div>&lt;div>&lt;div class="dp-highlighter bg_java">&lt;div class="bar">&lt;div class="tools">&lt;b>[java]&lt;/b>&amp;nbsp;&lt;a href="https://blog.csdn.net/btt2013/article/details/51051660#" class="ViewSource" title="view plain">view plain&lt;/a>&lt;span class="tracking-ad" data-mod="popu_168">&amp;nbsp;&lt;a href="https://blog.csdn.net/btt2013/article/details/51051660#" class="CopyToClipboard" title="copy">copy&lt;/a>&lt;div>&lt;/div>&lt;/span>&lt;span class="tracking-ad" data-mod="popu_169">&lt;/span>&lt;/div>&lt;/div>&lt;ol start="1" class="dp-j">&lt;li class="alt">&lt;span>&lt;span class="keyword">package&lt;/span>&lt;span>&amp;nbsp;cn.xbmu.oa.test;&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&lt;span class="keyword">import&lt;/span>&lt;span>&amp;nbsp;org.hibernate.SessionFactory;&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&lt;span class="keyword">import&lt;/span>&lt;span>&amp;nbsp;org.junit.Test;&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&lt;span class="keyword">import&lt;/span>&lt;span>&amp;nbsp;org.springframework.context.ApplicationContext;&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&lt;span class="keyword">import&lt;/span>&lt;span>&amp;nbsp;org.springframework.context.support.ClassPathXmlApplicationContext;&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="">&lt;span>&lt;span class="keyword">public&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="keyword">class&lt;/span>&lt;span>&amp;nbsp;SpringTest&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword">private&lt;/span>&lt;span>&amp;nbsp;ApplicationContext&amp;nbsp;ac&amp;nbsp;=&amp;nbsp;&lt;/span>&lt;span class="keyword">new&lt;/span>&lt;span>&amp;nbsp;ClassPathXmlApplicationContext(&lt;/span>&lt;span class="string">"applicationContext.xml"&lt;/span>&lt;span>);&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comment">//测试SessionFactory&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="annotation">@Test&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword">public&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="keyword">void&lt;/span>&lt;span>&amp;nbsp;testSessionFactory(){&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SessionFactory&amp;nbsp;sessionFactory&amp;nbsp;=&amp;nbsp;(SessionFactory)&amp;nbsp;ac.getBean(&lt;span class="string">"sessionFactory"&lt;/span>&lt;span>);&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;System.out.println(sessionFactory);&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>}&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;/ol>&lt;/div>使用Junit测试，结果：&lt;/div>&lt;div>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" alt="">&lt;/div>&lt;div>启动tomcat没有报错，说明以上环境的搭建都完全正确，并进行测试，也没有报错。&lt;/div>&lt;div>User.java&lt;/div>&lt;div>&lt;div class="dp-highlighter bg_java">&lt;div class="bar">&lt;div class="tools">&lt;b>[java]&lt;/b>&amp;nbsp;&lt;a href="https://blog.csdn.net/btt2013/article/details/51051660#" class="ViewSource" title="view plain">view plain&lt;/a>&lt;span class="tracking-ad" data-mod="popu_168">&amp;nbsp;&lt;a href="https://blog.csdn.net/btt2013/article/details/51051660#" class="CopyToClipboard" title="copy">copy&lt;/a>&lt;div>&lt;/div>&lt;/span>&lt;span class="tracking-ad" data-mod="popu_169">&lt;/span>&lt;/div>&lt;/div>&lt;ol start="1" class="dp-j">&lt;li class="alt">&lt;span>&lt;span class="keyword">package&lt;/span>&lt;span>&amp;nbsp;cn.xbmu.oa.domain;&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&lt;span class="keyword">public&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="keyword">class&lt;/span>&lt;span>&amp;nbsp;User&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword">private&lt;/span>&lt;span>&amp;nbsp;Long&amp;nbsp;id;&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword">private&lt;/span>&lt;span>&amp;nbsp;String&amp;nbsp;name;&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword">public&lt;/span>&lt;span>&amp;nbsp;Long&amp;nbsp;getId()&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword">return&lt;/span>&lt;span>&amp;nbsp;id;&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword">public&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="keyword">void&lt;/span>&lt;span>&amp;nbsp;setId(Long&amp;nbsp;id)&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword">this&lt;/span>&lt;span>.id&amp;nbsp;=&amp;nbsp;id;&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword">public&lt;/span>&lt;span>&amp;nbsp;String&amp;nbsp;getName()&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword">return&lt;/span>&lt;span>&amp;nbsp;name;&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword">public&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="keyword">void&lt;/span>&lt;span>&amp;nbsp;setName(String&amp;nbsp;name)&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword">this&lt;/span>&lt;span>.name&amp;nbsp;=&amp;nbsp;name;&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>}&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;/ol>&lt;/div>User.hbm.xml&lt;/div>&lt;div>&lt;div class="dp-highlighter bg_html">&lt;div class="bar">&lt;div class="tools">&lt;b>[html]&lt;/b>&amp;nbsp;&lt;a href="https://blog.csdn.net/btt2013/article/details/51051660#" class="ViewSource" title="view plain">view plain&lt;/a>&lt;span class="tracking-ad" data-mod="popu_168">&amp;nbsp;&lt;a href="https://blog.csdn.net/btt2013/article/details/51051660#" class="CopyToClipboard" title="copy">copy&lt;/a>&lt;div>&lt;/div>&lt;/span>&lt;span class="tracking-ad" data-mod="popu_169">&lt;/span>&lt;/div>&lt;/div>&lt;ol start="1" class="dp-xml">&lt;li class="alt">&lt;span>&lt;span class="tag">&amp;lt;?&lt;/span>&lt;span class="tag-name">xml&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">version&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"1.0"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">encoding&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"UTF-8"&lt;/span>&lt;span class="tag">?&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;lt;!DOCTYPE&amp;nbsp;hibernate-mapping&amp;nbsp;PUBLIC&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"-//Hibernate/Hibernate&amp;nbsp;Mapping&amp;nbsp;DTD&amp;nbsp;3.0//EN"&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"https://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">hibernate-mapping&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">package&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"cn.xbmu.oa.domain"&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">class&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">name&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"User"&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">id&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">name&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"id"&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">generator&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">class&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"native"&lt;/span>&lt;span class="tag">/&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">id&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">property&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">name&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"name"&lt;/span>&lt;span class="tag">/&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">class&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">hibernate-mapping&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;/ol>&lt;/div>&lt;/div>&lt;div>记得在hibernate.cfg.xml文件中引入映射文件。&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>TestService.java&lt;/div>&lt;div>&lt;div class="dp-highlighter bg_java">&lt;div class="bar">&lt;div class="tools">&lt;b>[java]&lt;/b>&amp;nbsp;&lt;a href="https://blog.csdn.net/btt2013/article/details/51051660#" class="ViewSource" title="view plain">view plain&lt;/a>&lt;span class="tracking-ad" data-mod="popu_168">&amp;nbsp;&lt;a href="https://blog.csdn.net/btt2013/article/details/51051660#" class="CopyToClipboard" title="copy">copy&lt;/a>&lt;div>&lt;/div>&lt;/span>&lt;span class="tracking-ad" data-mod="popu_169">&lt;/span>&lt;/div>&lt;/div>&lt;ol start="1" class="dp-j">&lt;li class="alt">&lt;span>&lt;span class="keyword">package&lt;/span>&lt;span>&amp;nbsp;cn.xbmu.oa.test;&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&lt;span class="keyword">import&lt;/span>&lt;span>&amp;nbsp;javax.annotation.Resource;&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&lt;span class="keyword">import&lt;/span>&lt;span>&amp;nbsp;org.hibernate.SessionFactory;&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&lt;span class="keyword">import&lt;/span>&lt;span>&amp;nbsp;org.hibernate.classic.Session;&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&lt;span class="keyword">import&lt;/span>&lt;span>&amp;nbsp;org.springframework.stereotype.Service;&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&lt;span class="keyword">import&lt;/span>&lt;span>&amp;nbsp;org.springframework.transaction.annotation.Transactional;&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="">&lt;span>&lt;span class="keyword">import&lt;/span>&lt;span>&amp;nbsp;cn.xbmu.oa.domain.User;&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&lt;span class="annotation">@Service&lt;/span>&lt;span>(&lt;/span>&lt;span class="string">"testService"&lt;/span>&lt;span>)&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&lt;span class="keyword">public&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="keyword">class&lt;/span>&lt;span>&amp;nbsp;TestService&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="annotation">@Resource&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword">private&lt;/span>&lt;span>&amp;nbsp;SessionFactory&amp;nbsp;sessionFactory;&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="annotation">@Transactional&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword">public&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="keyword">void&lt;/span>&lt;span>&amp;nbsp;saveTwoUser(){&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Session&amp;nbsp;currentSession&amp;nbsp;=&amp;nbsp;sessionFactory.getCurrentSession();&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;currentSession.save(&lt;span class="keyword">new&lt;/span>&lt;span>&amp;nbsp;User());&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword">int&lt;/span>&lt;span>&amp;nbsp;i&amp;nbsp;=&amp;nbsp;&lt;/span>&lt;span class="number">1&lt;/span>&lt;span>&amp;nbsp;/&amp;nbsp;&lt;/span>&lt;span class="number">0&lt;/span>&lt;span>;&lt;/span>&lt;span class="comment">//这里会抛出异常&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;currentSession.save(&lt;span class="keyword">new&lt;/span>&lt;span>&amp;nbsp;User());&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="">&lt;span>}&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;/ol>&lt;/div>SpringTest.java&lt;/div>&lt;div>&lt;div class="dp-highlighter bg_java">&lt;div class="bar">&lt;div class="tools">&lt;b>[java]&lt;/b>&amp;nbsp;&lt;a href="https://blog.csdn.net/btt2013/article/details/51051660#" class="ViewSource" title="view plain">view plain&lt;/a>&lt;span class="tracking-ad" data-mod="popu_168">&amp;nbsp;&lt;a href="https://blog.csdn.net/btt2013/article/details/51051660#" class="CopyToClipboard" title="copy">copy&lt;/a>&lt;div>&lt;/div>&lt;/span>&lt;span class="tracking-ad" data-mod="popu_169">&lt;/span>&lt;/div>&lt;/div>&lt;ol start="1" class="dp-j">&lt;li class="alt">&lt;span>&lt;span class="keyword">package&lt;/span>&lt;span>&amp;nbsp;cn.xbmu.oa.test;&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&lt;span class="keyword">import&lt;/span>&lt;span>&amp;nbsp;org.hibernate.SessionFactory;&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&lt;span class="keyword">import&lt;/span>&lt;span>&amp;nbsp;org.junit.Test;&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&lt;span class="keyword">import&lt;/span>&lt;span>&amp;nbsp;org.springframework.context.ApplicationContext;&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&lt;span class="keyword">import&lt;/span>&lt;span>&amp;nbsp;org.springframework.context.support.ClassPathXmlApplicationContext;&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="">&lt;span>&lt;span class="keyword">public&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="keyword">class&lt;/span>&lt;span>&amp;nbsp;SpringTest&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword">private&lt;/span>&lt;span>&amp;nbsp;ApplicationContext&amp;nbsp;ac&amp;nbsp;=&amp;nbsp;&lt;/span>&lt;span class="keyword">new&lt;/span>&lt;span>&amp;nbsp;ClassPathXmlApplicationContext(&lt;/span>&lt;span class="string">"applicationContext.xml"&lt;/span>&lt;span>);&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comment">//测试SessionFactory&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="annotation">@Test&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword">public&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="keyword">void&lt;/span>&lt;span>&amp;nbsp;testSessionFactory(){&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SessionFactory&amp;nbsp;sessionFactory&amp;nbsp;=&amp;nbsp;(SessionFactory)&amp;nbsp;ac.getBean(&lt;span class="string">"sessionFactory"&lt;/span>&lt;span>);&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;System.out.println(sessionFactory);&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comment">//测试事务&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="annotation">@Test&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword">public&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="keyword">void&lt;/span>&lt;span>&amp;nbsp;testTransaction(){&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;TestService&amp;nbsp;testService&amp;nbsp;=&amp;nbsp;(TestService)&amp;nbsp;ac.getBean(&lt;span class="string">"testService"&lt;/span>&lt;span>);&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;testService.saveTwoUser();&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>}&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;/ol>&lt;/div>测试事务，报错，因为在 int i = 1 / 0这里发生了异常。&lt;/div>&lt;div>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" alt="">&lt;br>查询数据库xbmuoa中的表，没有数据&lt;/div>&lt;div>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" alt="">&lt;/div>&lt;div>我们注释掉 &amp;nbsp;int i = 1 / 0;这句代码，重新测试，成功。&lt;/div>&lt;div>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" alt="">&lt;br>&lt;/div>&lt;div>查询user表，里面已经有了保存的数据&lt;/div>&lt;div>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" alt="">&lt;br>&lt;/div>&lt;div>我们，继续打开抛异常的语句，再测试；再注释抛异常的代码，再测试。查看表中的数据，发现了事务回滚了。&lt;/div>&lt;div>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" alt="">&lt;br>&lt;/div>&lt;div>到此为止，我们顺利的将Spring与Hibernate整合在一起了。并测试了SessionFactory与事务，都正常。&lt;/div>&lt;h2>&lt;a name="t5">&lt;/a>五、Spring与Struts整合：&lt;/h2>&lt;div>为了说明白，我们在整合之前写个Action，整合之后写个Action，看看他们之间的区别：&lt;/div>&lt;h3>&lt;a name="t6">&lt;/a>整合之前：&lt;/h3>&lt;div>TestAction.java&lt;br>&lt;/div>&lt;div>&lt;div class="dp-highlighter bg_java">&lt;div class="bar">&lt;div class="tools">&lt;b>[java]&lt;/b>&amp;nbsp;&lt;a href="https://blog.csdn.net/btt2013/article/details/51051660#" class="ViewSource" title="view plain">view plain&lt;/a>&lt;span class="tracking-ad" data-mod="popu_168">&amp;nbsp;&lt;a href="https://blog.csdn.net/btt2013/article/details/51051660#" class="CopyToClipboard" title="copy">copy&lt;/a>&lt;div>&lt;/div>&lt;/span>&lt;span class="tracking-ad" data-mod="popu_169">&lt;/span>&lt;/div>&lt;/div>&lt;ol start="1" class="dp-j">&lt;li class="alt">&lt;span>&lt;span class="keyword">package&lt;/span>&lt;span>&amp;nbsp;cn.xbmu.oa.test;&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&lt;span class="keyword">import&lt;/span>&lt;span>&amp;nbsp;com.opensymphony.xwork2.ActionSupport;&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&lt;span class="keyword">public&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="keyword">class&lt;/span>&lt;span>&amp;nbsp;TestAction&amp;nbsp;&lt;/span>&lt;span class="keyword">extends&lt;/span>&lt;span>&amp;nbsp;ActionSupport&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="annotation">@Override&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword">public&lt;/span>&lt;span>&amp;nbsp;String&amp;nbsp;execute()&amp;nbsp;&lt;/span>&lt;span class="keyword">throws&lt;/span>&lt;span>&amp;nbsp;Exception&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;System.out.println(&lt;span class="string">"----------&amp;gt;TestAction&amp;nbsp;execute()"&lt;/span>&lt;span>);&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword">return&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="string">"success"&lt;/span>&lt;span>;&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>}&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;/ol>&lt;/div>struts.xml&lt;/div>&lt;div>&lt;div class="dp-highlighter bg_html">&lt;div class="bar">&lt;div class="tools">&lt;b>[html]&lt;/b>&amp;nbsp;&lt;a href="https://blog.csdn.net/btt2013/article/details/51051660#" class="ViewSource" title="view plain">view plain&lt;/a>&lt;span class="tracking-ad" data-mod="popu_168">&amp;nbsp;&lt;a href="https://blog.csdn.net/btt2013/article/details/51051660#" class="CopyToClipboard" title="copy">copy&lt;/a>&lt;div>&lt;/div>&lt;/span>&lt;span class="tracking-ad" data-mod="popu_169">&lt;/span>&lt;/div>&lt;/div>&lt;ol start="1" class="dp-xml">&lt;li class="alt">&lt;span>&lt;span class="tag">&amp;lt;?&lt;/span>&lt;span class="tag-name">xml&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">version&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"1.0"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">encoding&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"UTF-8"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="tag">?&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;lt;!DOCTYPE&amp;nbsp;struts&amp;nbsp;PUBLIC&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"-//Apache&amp;nbsp;Software&amp;nbsp;Foundation//DTD&amp;nbsp;Struts&amp;nbsp;Configuration&amp;nbsp;2.3//EN"&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"https://struts.apache.org/dtds/struts-2.3.dtd"&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/li>&lt;li class="">&lt;span>&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">struts&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comments">&amp;lt;!--&amp;nbsp;配置为开发模式&amp;nbsp;--&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">constant&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">name&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"struts.devMode"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">value&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"true"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="tag">/&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comments">&amp;lt;!--&amp;nbsp;配置扩展名为action&amp;nbsp;--&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">constant&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">name&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"struts.action.extension"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">value&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"action"&lt;/span>&lt;span class="tag">/&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">package&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">name&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"default"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">namespace&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"/"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">extends&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"struts-default"&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comments">&amp;lt;!--&amp;nbsp;测试用的action&amp;nbsp;--&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="alt">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">action&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">name&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"test"&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">class&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"cn.xbmu.oa.test.TestAction"&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/span>&lt;/li>&lt;li class="">&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag">&amp;lt;&lt;/span>&lt;span class="tag-name">result&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;span class="attribute">name&lt;/span>&lt;span>=&lt;/span>&lt;span class="attribute-value">"success"&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>/test.jsp&lt;/span>&lt;span class="tag">&amp;lt;/&lt;/span>&lt;span class="tag-name">result&lt;/span>&lt;span class="tag">&amp;gt;&lt;/span>&lt;span>&amp;nbsp;</description></item><item><title>ssh框架所需jar包下载</title><link>https://pangyd.com/post/12-sshjar/</link><pubDate>Sun, 19 Nov 2017 19:47:05 +0800</pubDate><guid>https://pangyd.com/post/12-sshjar/</guid><description>&lt;div style="margin:1.5rem 0;padding:1rem;background:var(--bg-elev);border:1px solid var(--line);border-radius:10px;display:flex;flex-wrap:wrap;gap:.75rem;align-items:center">
 &lt;span class="mono" style="font-size:.8rem;color:var(--fg-muted)">附件&lt;/span>
 &lt;a href="https://pangyd.com/downloads/b738d7ec3094245c_b8d2446c657edba24f35968243fd3502.zip" download style="font-weight:600">ssh.zip&lt;/a>
&lt;/div></description></item><item><title>Java 异常处理的误区和经验总结</title><link>https://pangyd.com/post/172-java/</link><pubDate>Sat, 18 Nov 2017 22:29:47 +0800</pubDate><guid>https://pangyd.com/post/172-java/</guid><description>&lt;p>&lt;br>&lt;/p>&lt;div class="content rich" data-reactid=".0.1.0.0.0.1.1.1">&lt;p>&lt;span>本文着重介绍了 Java 异常选择和使用中的一些误区，希望各位读者能够熟练掌握异常处理的一些注意点和原则，注意总结和归纳。只有处理好了异常，才能提升开发人员的基本素养，提高系统的健壮性，提升用户体验，提高产品的价值。&lt;/span>&lt;/p>&lt;h2>&lt;span>误区一、异常的选择&lt;/span>&lt;/h2>&lt;p>&lt;span>图 1. 异常分类&lt;/span>&lt;/p>&lt;p>&lt;img class="" title="img001" data-src="https://pangyd.com/uploads/2017/11/74c10f869f038762.jpg" width="643" height="383" data-ratio="0.5956454121306376" data-w="643" data-type="png" data-backw="643" data-backh="383" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-fail="0" style="text-align: center">&lt;/p>&lt;p>&lt;span>图 1 描述了异常的结构，其实我们都知道异常分检测异常和非检测异常，但是在实际中又混淆了这两种异常的应用。由于非检测异常使用方便，很多开发人员就认为检测异常没什么用处。其实异常的应用情景可以概括为以下：&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>一、调用代码不能继续执行，需要立即终止。出现这种情况的可能性太多太多，例如服务器连接不上、参数不正确等。这些时候都适用非检测异常，不需要调用代码的显式捕捉和处理，而且代码简洁明了。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>二、调用代码需要进一步处理和恢复。假如将 SQLException 定义为非检测异常，这样操作数据时开发人员理所当然的认为 SQLException 不需要调用代码的显式捕捉和处理，进而会导致严重的 Connection 不关闭、Transaction 不回滚、DB 中出现脏数据等情况，正因为 SQLException 定义为检测异常，才会驱使开发人员去显式捕捉，并且在代码产生异常后清理资源。当然清理资源后，可以继续抛出非检测异常，阻止程序的执行。根据观察和理解，检测异常大多可以应用于工具类中。&lt;/span>&lt;/p>&lt;h2>&lt;span>误区二、将异常直接显示在页面或客户端。&lt;/span>&lt;/h2>&lt;p>&lt;span>将异常直接打印在客户端的例子屡见不鲜，以 JSP 为例，一旦代码运行出现异常，默认情况下容器将异常堆栈信息直接打印在页面上。其实从客户角度来说，任何异常都没有实际意义，绝大多数的客户也根本看不懂异常信息，软件开发也要尽量避免将异常直接呈现给用户。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>清单 1&lt;/span>&lt;/p>&lt;pre class="">&amp;nbsp;package&amp;nbsp;com.ibm.dw.sample.exception;/**&lt;br>&amp;nbsp;*&amp;nbsp;自定义&amp;nbsp;RuntimeException&lt;br>&amp;nbsp;*&amp;nbsp;添加错误代码属性&lt;br>&amp;nbsp;*/public&amp;nbsp;class&amp;nbsp;RuntimeException&amp;nbsp;extends&amp;nbsp;java.lang.RuntimeException&amp;nbsp;{&amp;nbsp;&lt;br>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//默认错误代码&amp;nbsp;&lt;br>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;static&amp;nbsp;final&amp;nbsp;Integer&amp;nbsp;GENERIC&amp;nbsp;=&amp;nbsp;1000000;&amp;nbsp;&lt;br>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//错误代码&lt;br>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private&amp;nbsp;Integer&amp;nbsp;errorCode;&amp;nbsp;&lt;br>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;RuntimeException(Integer&amp;nbsp;errorCode,&amp;nbsp;Throwable&amp;nbsp;cause)&amp;nbsp;{&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this(errorCode,&amp;nbsp;null,&amp;nbsp;cause);&lt;br>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;RuntimeException(String&amp;nbsp;message,&amp;nbsp;Throwable&amp;nbsp;cause)&amp;nbsp;{&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//利用通用错误代码&lt;br>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this(GENERIC,&amp;nbsp;message,&amp;nbsp;cause);&lt;br>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;RuntimeException(Integer&amp;nbsp;errorCode,&amp;nbsp;String&amp;nbsp;message,&amp;nbsp;Throwable&amp;nbsp;cause)&amp;nbsp;{&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;super(message,&amp;nbsp;cause);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.errorCode&amp;nbsp;=&amp;nbsp;errorCode;&lt;br>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;Integer&amp;nbsp;getErrorCode()&amp;nbsp;{&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;errorCode;&lt;br>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;br>}&lt;/pre>&lt;p>&lt;span>正如示例代码所示，在异常中引入错误代码，一旦出现异常，我们只要将异常的错误代码呈现给用户，或者将错误代码转换成更通俗易懂的提示。其实这里的错误代码还包含另外一个功能，开发人员亦可以根据错误代码准确的知道了发生了什么类型异常。&lt;/span>&lt;/p>&lt;h2>&lt;span>误区三、对代码层次结构的污染&lt;/span>&lt;/h2>&lt;p>&lt;span>我们经常将代码分 Service、Business Logic、DAO 等不同的层次结构，DAO 层中会包含抛出异常的方法，如清单 2 所示：&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>清单 2&lt;/span>&lt;/p>&lt;pre class="">public&amp;nbsp;Customer&amp;nbsp;retrieveCustomerById(Long&amp;nbsp;id)&amp;nbsp;throw&amp;nbsp;SQLException&amp;nbsp;{&amp;nbsp;//根据&amp;nbsp;ID&amp;nbsp;查询数据库}&lt;/pre>&lt;p>&lt;span>上面这段代码咋一看没什么问题，但是从设计耦合角度仔细考虑一下，这里的 SQLException 污染到了上层调用代码，调用层需要显式的利用 try-catch 捕捉，或者向更上层次进一步抛出。根据设计隔离原则，我们可以适当修改成：&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>清单 3&lt;/span>&lt;/p>&lt;pre class="">public&amp;nbsp;Customer&amp;nbsp;retrieveCustomerById(Long&amp;nbsp;id)&amp;nbsp;{&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try{&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//根据&amp;nbsp;ID&amp;nbsp;查询数据库&lt;br>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}catch(SQLException&amp;nbsp;e){&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//利用非检测异常封装检测异常，降低层次耦合&lt;br>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&amp;nbsp;new&amp;nbsp;RuntimeException(SQLErrorCode,&amp;nbsp;e);&lt;br>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}finally{&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//关闭连接，清理资源&lt;br>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br>}&lt;/pre>&lt;h2>&lt;span>误区四、忽略异常&lt;/span>&lt;/h2>&lt;p>&lt;span>如下异常处理只是将异常输出到控制台，没有任何意义。而且这里出现了异常并没有中断程序，进而调用代码继续执行，导致更多的异常。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>清单 4&lt;/span>&lt;/p>&lt;pre class="">&amp;nbsp;public&amp;nbsp;void&amp;nbsp;retrieveObjectById(Long&amp;nbsp;id){&amp;nbsp;&amp;nbsp;&amp;nbsp;try{&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//..some&amp;nbsp;code&amp;nbsp;that&amp;nbsp;throws&amp;nbsp;SQLException&lt;br>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}catch(SQLException&amp;nbsp;ex){&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;/**&lt;br>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*了解的人都知道，这里的异常打印毫无意义，仅仅是将错误堆栈输出到控制台。&lt;br>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*&amp;nbsp;而在&amp;nbsp;Production&amp;nbsp;环境中，需要将错误堆栈输出到日志。&lt;br>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*&amp;nbsp;而且这里&amp;nbsp;catch&amp;nbsp;处理之后程序继续执行，会导致进一步的问题*/&lt;br>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ex.printStacktrace();&lt;br>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br>}&lt;/pre>&lt;p>&lt;span>可以重构成：&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>清单 5&lt;/span>&lt;/p></description></item><item><title>关于烂代码的一切</title><link>https://pangyd.com/post/171/</link><pubDate>Fri, 17 Nov 2017 21:52:42 +0800</pubDate><guid>https://pangyd.com/post/171/</guid><description>&lt;p>&lt;br>&lt;/p>&lt;div class="content rich" data-reactid=".0.1.0.0.0.1.1.1">&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>当程序员经常听到您想要关注ABCD(需求文档/功能设计/架构设计/理解原则)时，编写代码只是将想法翻译成编程语言，这是一种技术内容。&lt;/p>&lt;p>当我听到这种观点的时候，会有一种近似于高寒的蔑视:你是一群傻X，不懂代码质量的重要性等等，这么下去迟早有一天会踩坑。&lt;/p>&lt;p>但几个月后，他们似乎没有进入坑里。随着编程技术的发展，带来了更多的我以前认为是傻X的人加入到程序员这个行业中来。&lt;/p>&lt;p>语言是越来越先进,封装,越来越完美,各种技术帮助程序员提高效率的生产代码,依赖于层的封装,程序员不需要知道的一些技术细节,只要翻译需求的内容逐行是好吗?&lt;/p>&lt;p>许多程序员不知道如何组织他们的代码，如何提高他们的效率，以及底层是如何基于他们在我的头脑中作为一段代码编写的。即使我认为他们写的代码是坨翔，但是从不接触代码的人的视角来看（比如说你的boss），代码编译过了，测试过了，上线运行了一个月都没出问题，你还想要奢求什么？&lt;/p>&lt;p>所以，即使不情愿，也必须承认，时至今日，写代码这件事本身没有那么难了。&lt;/p>&lt;p>许多程序员喜欢简单的东西:简单的函数名，简单的变量名，以及几句话来命名;缩写，缩写，省略，合并或合并。这种类型的代码编写的代码中有很多首字母缩写，没有人知道g /s/gos/ / / MSS，或一串不知道该怎么做的连续调用。&lt;/p>&lt;p>有很多程序员喜欢复杂，各种各样的宏定义，位和位，等等，所以代码似乎不能让它看起来很好。&lt;/p>&lt;p>简单地说，他们的代码是机器，而不是人。&lt;/p>&lt;p>不适当的组织是高级一些不好的代码，程序员写了一些代码，有基本的代码风格，但是对于更大的规模项目控制能力是不够的，不知道代码应该如何解耦，分层，和组织。&lt;/p>&lt;p>这种反模式现象经常出现在复制到项目的代码中;文件中有大量的代码;一个函数堆叠了几十万行;或者一个简单的函数，七到八圈的函数，在一个小的，难以找到的角落里无声地调用一些关键的逻辑。&lt;/p>&lt;p>这种代码的复杂度很高，很难修改，通常会发生崩溃;另一方面，创建代码的人倾向于修改代码，害怕创建代码，他们宁愿一步一步地复杂代码变得更加复杂，不愿意重新组织代码。当你面对几千行的时候，问你为什么不提取所谓的逻辑，他们说:&lt;/p>&lt;p>“这样会多一个类”&lt;/p>&lt;p>相反，如果一个项目的代码很难读，你能说这是糟糕的代码吗?这很难定义，可能不太好，但你能说它很糟糕吗?如果这个项目每次只维护一个人，而且这个人维护得很好，那么它似乎就是“足够的代码”。&lt;/p>&lt;p>许多项目刚刚开始只是一个小项目，而重点仅仅在于代码能够顺利地按时地运行。&lt;/p>&lt;p>过了一段时间后，其他人发现代码写的是问题，而不是理解，不敢移动。需求方又开始催促行，怎么办?我必须小心地改变逻辑，不移动结构，然后在注释中写出来，这样它就很丑，这样我就能理解内部的逻辑并重构它。&lt;/p>&lt;p>在一段时间内，也有类似的需要重用逻辑，只是要意识到代码具有不同特定场景的特殊逻辑，这对于重用非常麻烦。只需复制代码并更改它。问题解决了，问题翻了一倍。&lt;/p>&lt;p>几乎所有的“代码”进化的坏代码，代码不变，使用的代码场景发生了变化，最初的代码不符合新的场景，所以它变成了一个糟糕的代码。&lt;/p>&lt;p>从技术上讲，重构复杂代码时，要做三件事:理解旧代码，分解旧代码，构建新代码。要重构的旧代码通常很难理解;模块间的过度耦合导致了影响对整个身体的影响。旧代码不容易测试，不能保证新代码的正确性。&lt;/p>&lt;p>还有一个核心问题，重构的复杂性并不依赖于代码的复杂性。例如，如果你有1000行代码，重构需要1个小时，所以重构5000行代码需要2到3天的时间。重构一个失去控制的项目通常比重写它的效率要低。&lt;/p>&lt;p>在重构方面，重构也是一件非常困难的事情:很难直接从中获益，而且很难量化。这里有一个有趣的现象，几乎所有关于重构的书都有一个独立的章节，关于“如何向老板解释重构的需要”。&lt;/p>&lt;p>重构后你能提高多少效率?可以减少多少风险?很难说，糟糕的代码本身并不是一个简单的标准化的东西。&lt;/p>&lt;/div></description></item><item><title>Java面试基础知识--重点</title><link>https://pangyd.com/post/170-java/</link><pubDate>Fri, 17 Nov 2017 21:31:24 +0800</pubDate><guid>https://pangyd.com/post/170-java/</guid><description>&lt;p>1.面向对象的三大特性&lt;/p>&lt;div class="content rich" data-reactid=".0.1.0.0.0.1.1.1">&lt;p>&lt;span>继承、封装、多态&lt;/span>&lt;br>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>&lt;span>什么是继承?&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>①继承是面向对象程序设计能够提高软件开发效率的重要原因之一。&lt;/span>&lt;/p>&lt;p>&lt;span>②继承是具有传递性的，就像现实中孙子不仅长得像爸爸而且还像他爷爷。&lt;/span>&lt;/p>&lt;p>&lt;span>③继承来的属性和方法是隐式的，也就是在本类里面是看不见的。&lt;/span>&lt;/p>&lt;p>&lt;span>④一个类只能有一个父类，也就是类只能是单继承。&lt;/span>&lt;/p>&lt;p>&lt;span>⑤一个接口可以有多个父类，也就是接口可以是多继承。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>实际项目开发中，一个类继承于另一个类，那么前者就是后者的子类，反则反之。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>&lt;span>什么是封装?&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>对象数据和操作该对象的指令都是对象自身的一部分，能够实现尽可能对外部隐藏数据。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>实际项目开发中，使用封装最多的就是实体类，常常和 JavaBean (类必须是具体的和公共的，并且具有无参数的构造器)一起使用。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>&lt;span>那么，实体类有那些东西呢&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>答：私有的成员变量、无参数的构造器、有参数的构造器、setter和getters方法、重写tostring方法、重写hashCode和equals方法。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>&lt;span>什么是多态?&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>①多态就是对象拥有多种形态：引用多态和方法多态。&lt;/span>&lt;/p>&lt;p>&lt;span>②引用多态：父类的引用可以指向本类对象、父类的引用可以指向子类的对象。&lt;/span>&lt;/p>&lt;p>&lt;span>③方法多态：创建本类对象时，调用的方法为本类的方法；创建子类对象时，调用的方法为子类重写的方法或者继承的方法。&lt;/span>&lt;/p>&lt;p>&lt;span>④存在多态的必要条件：继承、重写。&lt;/span>&lt;/p>&lt;p>&lt;span>⑤多态的作用是消除类型之间的耦合关系。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>在实际项目开发中，A 类继承 B 类，如果在 A 类中不重写 B 类的方法的时候，输出的仍旧是 B 类方法里面的信息(B b=new A());如果在A类中重写 B 类的方法的时候，输出的是 A 类方法里面的信息(B b=new A())。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;/p>&lt;section class="" data-tools="135编辑器" data-id="90150">&lt;section>&lt;section data-width="100%">&lt;p class="" data-brushtype="text">&lt;span>2.Java集合框架树&lt;/span>&lt;/p>&lt;/section>&lt;/section>&lt;/section>&lt;p>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>&lt;span>Collection 接口：&lt;/span>&lt;/span>&lt;span>它是 Java 集合框架的一个根接口，也是List、Set和 Queue 接口的父接口。同时它定义了可用于操作 List、Set 和 Queue 的方法—增删改查。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p></description></item><item><title>Java后端程序员1年工作经验总结</title><link>https://pangyd.com/post/169-java1/</link><pubDate>Wed, 15 Nov 2017 19:26:07 +0800</pubDate><guid>https://pangyd.com/post/169-java1/</guid><description>&lt;p>&lt;span>&lt;span>1.引言&lt;/span>&amp;nbsp;&lt;/span>&lt;br>&lt;/p>&lt;p>　毕业已经一年有余，这一年里特别感谢技术管理人员的器重，以及同事的帮忙，学到了不少东西。这一年里走过一些弯路，也碰到一些难题，也受到过做为一名开发却经常为系统维护和发布当救火队员的苦恼。遂决定梳理一下自己所学的东西，为大家分享一下。&amp;nbsp;&lt;br>　　经过一年意识到以前也有很多认识误区，比如：&amp;nbsp;&lt;br>　　偏爱收集，经常收集各种资料视频塞满一个个硬盘，然后心满意足的看着容量不行动。&amp;nbsp;&lt;br>　　不重基础，总觉得很多基础东西不需要再看了，其实不懂的地方很多，计算机程序方面任何一个结果都必有原因，不要只会用不知道原理，那是加工厂出来的。现在ide查看代码那么方便，ctrl+点击就进入了JDK查看实现细节。&amp;nbsp;&lt;br>　　好高骛远，在计算机基础不牢固的情况下，总想着要做架构，弄分布式，搞大数据之类。&amp;nbsp;&lt;br>　　不重视性能，只求能实现功能，sql查询是不是可以优化，是否有算法妙用，大对象是否要清除。&amp;nbsp;&lt;br>　　不重视扩展性，模块之间紧密耦合，常用方法不提取成工具类，调用关系混乱等问题。&amp;nbsp;&lt;br>　　……&amp;nbsp;&lt;br>　　本文重点不在这些，故只列举了一小部分，下面进入正题。&lt;/p>&lt;p>&lt;span>2.语法基础&lt;/span>&lt;/p>&lt;p>　2.1 Java类初始化顺序&amp;nbsp;&lt;br>　　这是所有情况的类初始化顺序，如果实际类中没有定义则跳过：父类静态变量——父类静态代码块——子类静态代码块——父类非静态变量——父类非静态代码块——父类构造函数——子类非静态变量——子类非静态代码块——子类构造函数&amp;nbsp;&lt;br>　2.2 值传递和引用传递&amp;nbsp;&lt;br>　　可能很多人对此不屑一顾，心想老子都工作一年了，对这些还不熟悉吗？但实际情况并非这样，JDK中东西全部熟悉了吗？以一个最简单的例子开始，你觉得下图中代码执行完之后fatherList中的元素是什么？&amp;nbsp;&lt;br>&lt;/p>&lt;p>&lt;img class="" data-ratio="0.2854077253218884" data-src="https://pangyd.com/uploads/2017/11/74c10f869f038762.jpg" data-type="png" data-w="932" title="" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-fail="0">&lt;br>&lt;/p>&lt;p>　　这是一个最基础的值传递和引用传递的例子，你觉得好简单，已经想跃跃欲试的挑战了，那么请看下面的，StringBuffer很好理解，但是当你执行一遍之后发现是不是和预想中的输出不一样呢？String不是引用类型吗，怎么会这样呢？如果你无法理解，那么请看下String的实现源码，了解下其在内存中分配的实现原理。&amp;nbsp;&lt;br>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>　2.3 集合的使用&amp;nbsp;&lt;br>　　这部分几乎每个人都会用到，而且大家还都不陌生。下图来源于互联网，供大家复习一下。但是利用集合的特性进行巧妙的组合运用能解决优化很多复杂问题。Set不可重复性，List的顺序性，Map的键值对，SortSet/SortMap的有序性，我在工作中有很多复杂的业务都巧妙的使用了这些，涉及到公司保密信息，我就不贴出代码了。工作越久越发现这些和越巧妙。&amp;nbsp;&lt;br>　&lt;/p>&lt;p>&lt;img class="" data-ratio="0.9415094339622642" data-src="https://pangyd.com/uploads/2017/11/74c10f869f038762.jpg" data-type="jpeg" data-w="530" title="" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-fail="0">&lt;br>&lt;/p>&lt;p>　2.3 异常处理&amp;nbsp;&lt;br>　　1.看着try、catch、finally非常容易，如果和事务传播结合在一起，就会变得极其复杂。&amp;nbsp;&lt;br>　　2.finally不一定必须执行，return在catch/finally中处理情况（建议亲自操刀试一下）。&amp;nbsp;&lt;br>　　3.catch中可以继续抛自定义异常（并把异常一步步传递到控制层，利用切面抓取封装异常，返回给调用者）。&amp;nbsp;&lt;br>　2.4 面向对象思想&amp;nbsp;&lt;br>　　一提起面向对象，大家都知道抽象、封装、继承、和多态。但是实际工作经验中又知道多少呢，对于项目中如何巧用估计更不要提了。&amp;nbsp;&lt;br>　　共性的机会每个都需要用的建立基类，如每个控制层方法可能要通过security获取一个登录用户id，用于根据不同的用户操作不同的数据，可以抽象出一个应用层基类，实现获取id的protect方法。同理DAO层可以利用泛型提取出一个包含增删改查的基类。&amp;nbsp;&lt;br>　　多态的Override：基类的引用变量不仅可以指向基类的实例对象，也可以指向其子类的实例对象，如果指向子类的实例对象，其调用的方法应该是正在运行的那个对象的方法。在策略模式中使用很普遍。&amp;nbsp;&lt;br>　　提到面向对象，就不可避免的要说设计模式，在工作中，一个技术大牛写的一个类似策略模式（更复杂一点），十分巧妙的解决了各种业务同一个方法，并且实现了订单、工单、业务的解耦，看得我是非常佩服。我想很多面试中都会问道单例模式吧，还没有理解的建议去看一看。&lt;/p>&lt;p>&lt;span>3.多线程&lt;/span>&lt;/p>&lt;p>　3.1 线程安全&amp;nbsp;&lt;br>　　这个是老生常谈的问题了，但是确实是问题和bug高发区。线程同步问题不需要单独写了，想必大家都清楚，不太熟悉的建议百度一下。&amp;nbsp;&lt;br>　3.1.1 线程安全问题&amp;nbsp;&lt;br>　　1.代码中如果有同步操作，共享变量要特别注意（这个一般都能意识到）&amp;nbsp;&lt;br>　　2多个操作能修改数据表中同一条数据的。（这个容易被忽略，业务A可能操作表a，业务B也可以操作表a，业务A、B即使在不同的模块和方法中，也会引起线程安全问题。例如如果一个人访问业务A接口，另一个人访问业务B接口，在web中每个业务请求都是会有单独的一个线程进行处理的，就会出现线程安全问题）。&amp;nbsp;&lt;br>　　3.不安全的类型使用，例如StringBuffer、StringBuild，HashTable、HashMap等。在工作中我就遇到过有人在for循环进行list的remove，虽然编译器不报错，程序可以运行，但是结果却可想而知。&amp;nbsp;&lt;br>　　4.Spring的bean默认是单例的，如果有类变量就要特别小心了（一般情况下是没人在控制层、业务层、DAO层等用类变量的，用的话建议是final类型，例如日志log，gson等）。&amp;nbsp;&lt;br>　　5.多个系统共享数据库情况，这个其实和分布式系统类似&amp;nbsp;&lt;br>　　用户重复提交问题（即使代码中从数据库读取是否存在进行限制不能解决问题）&amp;nbsp;&lt;br>　3.1.2 线程安全解决&amp;nbsp;&lt;br>　　在需要同步的地方采用安全的类型。&amp;nbsp;&lt;br>　　JDK锁机制，lock、tryLock，synchronized，wait、notify、notifyAll等&amp;nbsp;&lt;br>　　Concurrent并发工具包，在处理一些问题上，谁用谁知道。强烈建议查看源码！&amp;nbsp;&lt;br>　　数据表加锁。（除非某个表的访问频率极低，否则不建议使用）&amp;nbsp;&lt;br>　　涉及分布式的，采用中间件技术例如zookeeper等解决。&amp;nbsp;&lt;br>　3.2 异步&amp;nbsp;&lt;br>　　异步使用场景不影响主线程，且响应较慢的业务。例如IO操作，第三方服务（短信验证码、app推送、云存储上传等）。&amp;nbsp;&lt;br>　　如果异步任务很多，就需要使用任务队列了，任务队列可以在代码级别实现，也可以利用redis（优势太明显了）。&amp;nbsp;&lt;br>　3.3 多线程通信&amp;nbsp;&lt;br>　　这方面文章非常多，这里不在详述。&amp;nbsp;&lt;br>　　1.共享变量方式（共享文件、全局变量，信号量机制等）&amp;nbsp;&lt;br>　　2.消息队列方式&amp;nbsp;&lt;br>　　3. 忙等，锁机制&amp;nbsp;&lt;br>　3.4多线程实现&amp;nbsp;&lt;br>　　1.集成Thread类，重写（这里的重写指的是override）run方法，调用start方法执行。&amp;nbsp;&lt;br>　　2.实现Runable接口，实现run方法，以Runable实例创建thread对象。&amp;nbsp;&lt;br>　　3.实现Callable接口，实现call方法，FutureTask包装callable接口，FutureTask对象创建thread对象，常用语异步操作，建议使用匿名内部类，方便阅读和使用。&amp;nbsp;&lt;br>　　额外需要说明的是：&amp;nbsp;&lt;br>　　1.理解thread的join方法；&amp;nbsp;&lt;br>　　2.不要认为volitate是线程安全的（不明白原因的建议去看jvm运行时刻内存分配策略）；&amp;nbsp;&lt;br>　　3.sleep时间片结束后并不保证立马获取cpu。&amp;nbsp;&lt;br>　　4.ThreadLocal能够为每一个线程维护变量副本，常用于在多线程中用空间换时间。&amp;nbsp;&lt;br>&lt;/p></description></item><item><title>程序员到底累不累，其实正真的程序员比谁都轻松，不信你看</title><link>https://pangyd.com/post/168/</link><pubDate>Wed, 15 Nov 2017 19:23:08 +0800</pubDate><guid>https://pangyd.com/post/168/</guid><description>&lt;h2 class="rich_media_title" id="activity-name">&lt;span>说到底，是自己的选择问题。&lt;/span>&lt;/h2>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>三百六十行，哪行容易？&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>但关键是自己的心态，如果工作成了你的负担和困扰，你得有跳出来的勇气和行动力。&lt;/span>&lt;/p>&lt;p>&lt;span>我自己先后就职于虎扑体育、爱奇艺和凯英网络，担任iOS研发经理，有6年工作经验，4年的iOS开发经验，2年的管理经验，1年的服务器端开发经验。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>就职于大公司期间，我的工资已经算是高薪了，前途逐渐明朗。我已经看到了：如果沿着这条路走下去，可能生活是稳定顺畅的。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>可是虽然工资不断攀升，身体和生活也出了一些问题：我发现自己陷入了工作生活不分开的死循环，哪怕周末也是一直在想着工作，完全没有自己的生活。几年下来，各种身体问题开始涌现。大公司里面频繁又无意义的会议让我厌烦，压抑的工作氛围也让我觉得难以忍受。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>有天觉得这样不行，再这样下去身体会废掉，整个人状态也不好。一番犹豫之后，我痛下决心，想离开目前这种温水煮青蛙的生活。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>于是我放弃了大公司的高薪，换了一份工作。&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>还是做技术，但这份工作和以往最大的差别就在于：这份工作是远程办公。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>我可以自由的安排自己的工作时间，可以摆脱公司没完没了的会议，更加高效地工作，省去上下班的时间，更多的用来享受生活。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>换工作只是一个开始，不过也引起了一连串生活方式的改变。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>我开始去徒步旅行。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>去过了尼泊尔 Poolhill、江西武功山、浙江七尖、徽杭古道、仙霞古道，假期基本都在路上。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>我开始在上海各个咖啡馆敲代码。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;img data-s="300,640" data-type="jpeg" data-src="https://pangyd.com/uploads/2017/11/74c10f869f038762.jpg" data-copyright="0" class="" data-ratio="0.5636363636363636" data-w="550" data-backw="550" data-backh="310" width="100%" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-fail="0">&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;br>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>这工作环境，秒杀大公司惨白的灯光、压抑的环境好几个档次好嘛！&lt;/span>&lt;/p>&lt;p>&lt;span>我开始健身。人变得挺拔多了，和产品据理力争的时候不用担心挨揍。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>我开始阅读。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;img data-s="300,640" data-type="jpeg" data-src="https://pangyd.com/uploads/2017/11/74c10f869f038762.jpg" class="" data-backw="556" data-backh="370" data-croporisrc="https://mmbiz.qpic.cn/mmbiz_jpg/JfI4bJ7rK0l8ib38obyZ9T2ex1ibOjK6qcyrXDQwMcYCvZLbGg3UWuHccq9e0qzudfv8XCp8ibkAZqOvJ5HHwMQ3w/0?wx_fmt=jpeg" data-cropx1="0" data-cropx2="1000" data-cropy1="0" data-cropy2="631.2949640287769" data-ratio="0.631" data-w="1000" width="556px" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-fail="0">&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;br>&lt;/p>&lt;p>&lt;span>是一种出于兴趣和好奇而进行的更广泛的阅读，通过旅行和阅读发现更大的世界。&lt;/span>&lt;/p></description></item><item><title>看十万程序员总结：优秀的程序员和码农差别在哪？</title><link>https://pangyd.com/post/167/</link><pubDate>Sun, 12 Nov 2017 19:55:45 +0800</pubDate><guid>https://pangyd.com/post/167/</guid><description>&lt;p>程序员的水平必然有高有低，工资更是相差极大，而且有些时候，工作年限少的还会比工作年限多的人工资更高，那么，程序员的水平如何衡量？来看看网友怎么说。&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>当然，一定会有更加优秀的程序员，可能我们见到的比较少吧。&lt;/p></description></item><item><title>Java精选笔试题</title><link>https://pangyd.com/post/166-java/</link><pubDate>Sat, 11 Nov 2017 20:50:26 +0800</pubDate><guid>https://pangyd.com/post/166-java/</guid><description>&lt;p>&lt;span>合抱之木，生于毫末；九层之台，起于垒土；千里之行；始于足下。赶快测测你的Java基础知识掌握的如何？&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;/p>&lt;p>&lt;img class="" data-ratio="0.5625" data-s="300,640" data-src="https://pangyd.com/uploads/2017/11/74c10f869f038762.jpg" data-type="jpeg" data-w="640" width="100%" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-fail="0">&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;/p>&lt;section data-role="outer" label="Powered by 135editor.com">&lt;section class="" data-tools="135编辑器" data-id="86516">&lt;section>&lt;h4>&lt;span>&lt;span>1，volatile关键字是否能保证线程安全？（）&lt;/span>&lt;/span>&lt;/h4>&lt;/section>&lt;/section>&lt;/section>&lt;p>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;/p>&lt;p>&lt;/p>&lt;section data-role="outer" label="Powered by 135editor.com">&lt;section class="" data-tools="135编辑器" data-id="85988">&lt;section data-width="100%">&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;/section>&lt;/section>&lt;section class="" data-tools="135编辑器" data-id="85988">&lt;section data-width="100%">&lt;p>&lt;span>&amp;gt;&lt;/span>&lt;span>&amp;gt;&lt;/span>&lt;span>&amp;gt;&lt;/span>&lt;span>&amp;gt;&lt;/span>&lt;/p>&lt;section>&lt;p class="" data-brushtype="text">&lt;span>答案：否&lt;/span>&lt;/p>&lt;/section>&lt;/section>&lt;/section>&lt;p>&lt;br>&lt;/p>&lt;/section>&lt;p>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;/p>&lt;p>&lt;span>volatile关键字用在多线程同步中，可保证读取的可见性，JVM只是保证从主内存加载到线程工作内存的值是最新的读取值，而非cache中。但多个线程对volatile的写操作，无法保证线程安全。&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>假如线程1，线程2 在进行read,load 操作中，发现主内存中count的值都是5，那么都会加载这个最新的值，在线程1对count进行修改之后，会write到主内存中，主内存中的count变量就会变为6；线程2由于已经进行read,load操作，在进行运算之后，也会更新主内存count的变量值为6；导致两个线程及时volatile关键字修改之后，还是会存在并发的情况。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;/p>&lt;section data-role="outer" label="Powered by 135editor.com">&lt;section class="" data-tools="135编辑器" data-id="86516">&lt;section>&lt;h4>&lt;span>&lt;span>2，下面哪个流类属于面向字符的输入流(&amp;nbsp; )&lt;/span>&lt;/span>&lt;/h4>&lt;/section>&lt;/section>&lt;/section>&lt;p>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>A、BufferedWriter&lt;/span>&lt;/p>&lt;p>&lt;span>B、FileInputStream&lt;/span>&lt;/p>&lt;p>&lt;span>C、ObjectInputStream&lt;/span>&lt;/p>&lt;p>&lt;span>D、InputStreamReader&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;/p>&lt;section data-role="outer" label="Powered by 135editor.com">&lt;section class="" data-tools="135编辑器" data-id="85988">&lt;section data-width="100%">&lt;section>&lt;span>&amp;gt;&lt;/span>&lt;span>&amp;gt;&lt;/span>&lt;span>&amp;gt;&lt;/span>&lt;span>&amp;gt;&lt;/span>&lt;/section>&lt;section>&lt;p class="" data-brushtype="text">&lt;span>答案：D&lt;/span>&lt;/p></description></item><item><title>听说程序员秃顶是尊贵身份的象征？</title><link>https://pangyd.com/post/165/</link><pubDate>Fri, 10 Nov 2017 22:22:57 +0800</pubDate><guid>https://pangyd.com/post/165/</guid><description>&lt;p style="text-align: center">&lt;span>作为一名程序员必须知道的事情：女怕嫁错郎，男怕入错行，程序猿最怕就是选错语言！&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p style="text-align: center">&lt;span>选择一门牛逼的编程语言是每一位程序员进入IT江湖的头等大事。为什么？选择语言就像投资买房，选对了，是北上广深，选错了，就是“鄂尔多斯”【有房无价】：to be or not to be！？&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p style="text-align: center">&lt;span>那么，如何选择牛逼的编程语言？&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p style="text-align: center">&lt;span>想知道秘笈吗？&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;br>&lt;/p>&lt;p style="text-align: center">&lt;img data-s="300,640" data-type="jpeg" data-src="https://pangyd.com/uploads/2017/11/74c10f869f038762.jpg" data-ratio="1.3392857142857142" data-w="224" class="" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-fail="0">&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p style="text-align: center">&lt;span>编程语言是人写的，冥冥大道，&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;span>编程语言的运势同创始人密不可分。&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;span>气运旺盛的语言，必然是其创始人用心血滋补养育，&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;span>经过老九君仔细盘查发现，这其中最直观的表现，&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;span>&lt;span>就是编程语言之父们头顶的发量！！！&lt;/span>&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;span>是的，你没看错，老九君一般不轻易泄露天机！&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;img data-s="300,640" data-type="jpeg" data-src="https://pangyd.com/uploads/2017/11/74c10f869f038762.jpg" data-ratio="0.7192429022082019" data-w="317" class="" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-fail="0">&lt;/p>&lt;p style="text-align: center">&lt;span>列举如下，小伙伴们可借此参考。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p style="text-align: center">&lt;span>&amp;nbsp;&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;span>【一】&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>我们首先来看Java语言，这几年大数据、Android、微服务的大行其道而如日中天【三个领域均在开发中均会使用大量Java代码】。这在1998年Java刚出道时，很多人是完全预料不到的。但如果我们看看Java之父James Gosling的头顶茂密指数，便一目了然。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p style="text-align: center">&lt;img class="" data-ratio="0.78" data-s="300,640" data-src="https://pangyd.com/uploads/2017/11/74c10f869f038762.jpg" data-type="jpeg" data-w="300" width="auto" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-fail="0">&lt;br>&lt;/p></description></item><item><title>一线城市年薪四十万以上的程序员，他的真实生活状态是怎样的？</title><link>https://pangyd.com/post/164/</link><pubDate>Thu, 09 Nov 2017 18:15:01 +0800</pubDate><guid>https://pangyd.com/post/164/</guid><description>&lt;p>一线城市年薪四十万以上的程序员，他的真实生活状态是怎样的？&lt;/p>&lt;p>假设是税前40w，而职位还只是程序员，那一般情况下是在中大型互联网公司了。传统软件行业不是给不了年薪40，但是在传统软件行业拿40w年薪的一般来说都是中层以上的管理岗了，就算曾经是程序员，生活状态也不一样了。也不是创业型公司，虽然的确创业型公司都说给的工资高，但是拿年薪40来招多半都是招的架构师岗了，而创业型公司也不需要太多架构师，所以这个架构师说不定还是首席架构师了，跟程序员的生活还是有一定差距。同时，不要觉得40万是个好大的数，说的是年薪，互联网公司一般是发13到16个月的薪水，所以40w算到每个月也就是20k到30k，这个薪水也就是个高级开发的职位。那么问题就简化为在中大型互联网公司高级开发工程师的生活状态。互联网公司节奏快，发展快，所以会有很多需求，高级开发每天要做的事就是手上有需求或者项目要编码的时候就在编码，有需求要立项的时候就会被产品叫去开会，产品PRD出来的时候就在做设计，设计出来就编码，编码完成就提交测试，测试测出bug就改bug，测完就上线。除此之外线上有问题的时候必须第一时间响应，无论问题大小，如果能通过运维手段解决的问题需要立刻执行。如果开发时间充足，上线顺利，线上没有问题的话，程序员也不会经常加班，该回家的还是回家，该去健身的还是会去健身，该调戏产品或者测试妹纸的还是会去调戏。周末的话，开发任务紧的话就去加班，开发任务不紧的话也就各自过各自的生活。题目问40w的程序员什么生活状态，其实40w的程序员生活状态跟30w，20w的一样，他拿40w并不是说他就要干的时间比别人多，不是说拿40w就要加班多。拿40w和拿20w的区别在于拿40w的要站在一定的高度想问题，要用他的经验和知识带着20w干活，少走弯路少掉坑，这才是40w的价值。而不是体现在加班上面的。&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>在外行看来，年薪四十万以上的程序员生活应该是很滋润的那种，我当初刚毕业也是那么觉得的。但是现实中，拿的起这工资的一般都是管理层，没有过硬的技术一般是拿不起那工资的，职位最低也是项目组组长（只限大公司）。一旦项目入手，管理不比底层轻松，要考虑的不只是单模块的功能和架构，涉及层次方面太多了。项目上线前和上线后也是最累的时候，加班也是家常便饭，不到早上1点的还不算加班。平时而且也没太多时间，拿着钱到处娱乐消遣的，技术还是要每天不短的学习消化，IT发展技术发展太快了，必须要时刻跟上步伐。&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>一线城市40w年薪以上的程序员一般有两种人，第一种，在互联网公司工作，薪水较高，但工作压力也相对较大，也就是常说的996。第二种，就是一些年龄较大的专家级程序员（架构师），压力可能没有互联网公司的大，且凭借强大的技术能力和知识面以及项目经验在一些中等或大型公司中担任顾问的岗位，也有可能在小公司中以技术入股的形式担任相关职位。但不管是哪种人，以下两点非常重要，就是过硬的技术能力和持续的学习能力。坐标北京，也算程序员高薪聚集地了吧！假设该名程序员年薪税后40万，那就约等于每个月3万多一点，当然可能有一些年终奖或者是14或15月薪你，这就不细算了。月薪3万的程序员起码得有个3年及以上工作经验了（研究生博士生也按年折算为工作经验），这还得是互联网企业，传统企业怕是给不了这么多的。互联网企业一大特点就是加班！加班！每天起码得有10几个小时扑在工作上，其余时间除了休息就是浪费在了通勤路上。&lt;/p>&lt;p>如果这个程序员还没买房并且也不打算在北京买房或者已经有房子了，这些钱倒是可以过得潇洒。如果打算在北京买房，按照一平米5万，买个80平来算的话，首付就得120万，这还不是学区房。所以说，年薪40万得分有没有房才能决定过的怎么样！深圳、上海等地房价也不便宜，同理！&lt;/p></description></item><item><title>程序员如何高效学习（以 Java 为例）</title><link>https://pangyd.com/post/163-java/</link><pubDate>Thu, 09 Nov 2017 18:10:09 +0800</pubDate><guid>https://pangyd.com/post/163-java/</guid><description>&lt;blockquote>&lt;p>写在前面：&lt;/p>&lt;p>其实学习是一件很私人的事情，每个人都应该有一套自己的学习方式，而不是照搬照抄别人的。适合别人的不一定适合自己。所以，读这篇分享的时候，请以一种&lt;span>这点是不是对我有帮助&lt;/span>的心态来阅读，&lt;span>而不是&lt;/span>&lt;span>原来我要这样才能学的好&lt;/span>的心态。如果你觉得某一点对你有用，那就记在心里，如果你觉得不太适合你，那么一笑而过就好。&lt;/p>&lt;/blockquote>&lt;p>&lt;br>&lt;/p>&lt;p>我不是什么大牛，只是一个普通的本科生，有说的不好的地方，还望海涵。也因为我只是一个本科生，没有很多的工作经验，所以对于工作后的一些学习经验比较匮乏，所以文章里大部分说的都是大学时期的一些经验，很抱歉。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>这篇文章大体上会从以下几个部分展开：&lt;/p>&lt;ul class=" list-paddingleft-2">&lt;li>&lt;p>认清自己&lt;/p>&lt;/li>&lt;li>&lt;p>学习目的&lt;/p>&lt;/li>&lt;li>&lt;p>时间管理&lt;/p>&lt;/li>&lt;li>&lt;p>学习方法&lt;/p>&lt;/li>&lt;li>&lt;p>学习的步骤&lt;/p>&lt;/li>&lt;li>&lt;p>获取知识的途径&amp;nbsp;&lt;/p>&lt;/li>&lt;li>&lt;p>影响学习的几个因素&amp;nbsp;&lt;/p>&lt;/li>&lt;li>&lt;p>自己的心态&lt;/p>&lt;/li>&lt;li>&lt;p>外物的影响&lt;/p>&lt;/li>&lt;li>&lt;p>其他想说的&amp;nbsp;&lt;/p>&lt;/li>&lt;li>&lt;p>大学生的学习&amp;nbsp;&lt;/p>&lt;/li>&lt;li>&lt;p>一些感悟&lt;/p>&lt;/li>&lt;/ul>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>&lt;span>一、认清自己&lt;/span>&lt;/span>&lt;/p>&lt;p>1.1&lt;/p>&lt;p>认清自己最关键的一点是要&lt;span>知道自己到底想要什么&lt;/span>。这是第一步，也是最重要的一步。因为这关系到你能够&lt;span>选对学习方向&lt;/span>，能否&lt;span>沉下心来去学习&lt;/span>。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>我们都知道，&lt;span>做自己感兴趣的事情的时候，是可以事半功倍的&lt;/span>，因为你愿意去做它，而不是出于某种原因不得不去做。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>经常会有人问我，现在前端找工作好找么？java 找工作好找么？我要不要学 android 呢？这些问题的答案其实大家心里都明白：只要你足够优秀，学什么都能够找到一份好的工作。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>所以说，&lt;span>不要因为某一个方向火，而盲目的去追；也不要因为某一个方向可能不容易找工作而不去学。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>对一个搞技术的人来说，年龄的增长其实不是那么可怕，可怕的是你没有&lt;span>匹配自己年龄的技术深度&lt;/span>。当你的工作换一个刚毕业的学生都能做的时候，你很快就会被淘汰了。所以，选方向一定要选自己感兴趣的方向，因为只有这样，&lt;span>你才有兴趣去往深入了学，你才不会在未来被年轻人挤下去。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>1.2&lt;/p>&lt;p>认清自己的第二点是&lt;span>认识到人外有人&lt;/span>。自满，自大，自欺欺人是影响自己进步的绊脚石。如果你觉得，你现在已经很了不起了，你能做到这个程度已经很不错了，你就会停滞不前，然后浪费大把的时间。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;blockquote>&lt;p>这是我自己的亲身经历。我的学校是一个双非大学，计算机也不是学校很好的专业，消息也比较闭塞。在我的圈子里，我觉得自己已经很不错了，我之前也一直这样认为。但是，当我今年开始准备春招准备校招的时候，我发现我错了，&lt;span>和真正优秀的人比起来，我什么都不是&lt;/span>。以前觉得自己会的东西，出去一看，大家其实都会；以前觉得很多知识等工作了再去学也不迟，出去一看，发现早就有人学会了。但是，现在认识到这些已经有点晚了，因为已经开始找工作了，没有时间再去让你从头开始学了。&lt;/p>&lt;/blockquote>&lt;p>&lt;br>&lt;/p>&lt;p>所以说，永远不要自满，要知道人外有人。&lt;span>如果有一天，你觉得周围没有人比你更厉害了，一定要记得，不是你走到巅峰了，而是你的圈子，应该扩大了。&lt;/span>只有你的周围，有很多更厉害的人，你才能意识到自己的不足。这也是我常挂在嘴边的：&lt;span>你想变成什么样的人，你就要去认识什么样的人，你的周围是什么样的人，你就会变成什么样的人。&lt;/span>要知道，人以群分。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>&lt;span>二、学习的目的&lt;/span>&lt;/span>&lt;/p>&lt;p>为什么要学习呢？&lt;span>学习的目的，根本上是为了获取竞争优势，增加选择机会。&lt;/span>你比别人懂得多，比别人学的深，你就更有竞争力。对于程序员来说，不懂得学习是没有办法在这个行业混下去的。技术的更新换代，技术的深入掌握都需要去不断的学习，如果你不学，很快就会被淘汰了。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>找工作的时候，有其他专业的朋友会羡慕的和我说：你这个专业真好，一毕业月薪就上万，我才 3，4 千。其实我想说的是，如果不好好学习技术，搞技术的也会失业。大部分的人都只看到一部分计算机的应届生工资很高很羡慕，却忽略了他们这四年是怎么度过的。天上是不会掉馅饼的，计算机专业的每天看剧打游戏，毕业一样找不到工作。希望以后你不会是那群天天打游戏看剧最后抱怨自己工资低的那群人中的一个。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>&lt;span>三、时间管理&lt;/span>&lt;/span>&lt;/p>&lt;p>知道了自己的方向，知道了为什么要学，那么我们接下来谈一谈，怎么安排自己的时间，或者说，&lt;span>怎么制定一个计划&lt;/span>。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>很多人应该都有过这样的经历：我现在很无聊，不知道做什么好，学习吧，不知道学什么，打开电脑也不知道做什么，打开手机也不知道做什么，然后只能选择看个直播，看个电视或者打个游戏来打发时间。当一天过去以后，突然后悔，觉得自己当时要是学习就好了。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>为什么会这样呢？是因为你自己没有一个计划，如果你每天都有一个按时间段安排的计划的话，你就不会迷茫了，你就会知道这个时间点自己应该做什么，而不是用看剧打游戏来打发时间。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>关于时间的管理，首先&lt;/span>：&lt;/p>&lt;blockquote>&lt;p>要有一个大一点的计划，比如年计划，月计划，周计划。&lt;/p>&lt;p>这一年大体上要打到什么目标，这个月要学习哪些知识。&lt;/p>&lt;p>然后是精确到小时的日计划。&lt;/p>&lt;p>每一天，哪个时间段做什么都详细的列出来。&lt;/p>&lt;/blockquote>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>其次，不要太盲目自信。&lt;/span>很多人其实从来没有完成过自己的计划。如果你真的能够完成你制定的每一个计划，那现在的你一定已经很了不起了。如果你几乎没有完成过自己的计划，那么你一开始制定日计划的时候，不要给自己太多的任务。因为如果你一旦完不成，就会影响自己的信心。最好的方式是，&lt;span>一开始制定一些简单的计划，然后每天很容易就能做到，然后慢慢的去增加自己每天的任务量。&lt;/span>最后找到一个最适合自己的节奏。这个过程可能需要很长的时间，因为你要&lt;span>不断的去尝试，去改进&lt;/span>。找到最适合自己的作息时间去休息，找到自己工作状态最好的时间去工作等等。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>最后，不要把你的计划当摆设。虽然我上面说过，&lt;span>很多人其实从来没有完成过自己的计划&lt;/span>。但是我还是希望你能够&lt;span>认真的去对待它&lt;/span>，因为受益的有且只有你自己。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>&lt;span>四、学习方法&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>盲目的学习效果并不好。以前看书的时候，看完一遍再从头看，感觉就像是在看一本新书，完全没有印象。看似自己学了不少，其实真正掌握到的并不多。学习不是你看得书越多，读过的文章越多你就学的越好，而是看你究竟掌握了多了。那么，&lt;span>怎么才能有效的去学习一门新的技术呢&lt;/span>？我总结了以下几个步骤。&lt;/p>&lt;p>&lt;br>&lt;/p></description></item><item><title>程序员被误贴的“六大标签”，你中招了吗？</title><link>https://pangyd.com/post/162/</link><pubDate>Wed, 08 Nov 2017 19:35:50 +0800</pubDate><guid>https://pangyd.com/post/162/</guid><description>&lt;div class="userinfo" data-reactid=".0.1.0.0.0.1.1.0" style="text-align: start">&lt;span class="username" data-reactid=".0.1.0.0.0.1.1.0.0">&lt;br class="Apple-interchange-newline">绅士稀有&lt;/span>&lt;span class="male" data-reactid=".0.1.0.0.0.1.1.0.1">&lt;/span>&lt;span data-reactid=".0.1.0.0.0.1.1.0.2">&lt;span class="honour " data-reactid=".0.1.0.0.0.1.1.0.2.$">&lt;/span>&lt;/span>&lt;/div>&lt;div class="content rich" data-reactid=".0.1.0.0.0.1.1.1" style="text-align: start">&lt;p>程序员这个群体，常常被外行人贴上一些错误的标签。今天小编将这些标签整理了一下，快看看你中招了吗？&lt;/p>&lt;p>&lt;strong>排名一：生活邋遢&lt;/strong>&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>可以说很多人都在吐槽程序员的生活邋遢，由于工作忙碌的原因，他们常常不修边幅，穿着打扮各方面都是比较随意的。但在我看来，很多程序员早已注意到这个问题，所以他们也开始走“精致生活”路线。无论是穿衣打扮，还是日常生活习惯，都是非常优秀的。&lt;/p>&lt;p>&lt;strong>排名二：修电脑的&lt;/strong>&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>“你是程序员对吧？”&lt;/p>&lt;p>“是啊，怎么了？”&lt;/p>&lt;p>“那你帮我修一下电脑吧。”&lt;/p>&lt;p>一般这种尬聊直接的后果就是友尽。很多不了解程序员的人认为，程序员就是写代码的，修电脑应该也是一把好手。在这种神逻辑的驱使下，他们往往是话题终结者。在这里，小编郑重告诉大家：程序员虽然每天编程要和电脑打交道，但他们真没有修电脑这种技能。所以请不要再把天聊死了。&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>&lt;strong>排名三：不会拍照&lt;/strong>&lt;/p>&lt;p>很多妹子都表示自己的程序员男朋友不会拍照，比如说自己的大长腿拍成了短粗腿。&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>但这里要为程序员正名，其实不会拍照的男生很多，为什么非要把这个锅甩给我们程序员。这个锅，我们不背不背。就我的了解，身边的很多程序员朋友都有摄像的爱好，他们入手专业的摄像设备，而且会找一些摄影的兼职。咳咳，当然偶尔会在三里屯的街头拍些好看的妹纸什么的。&lt;/p>&lt;p>&lt;strong>排名四：死宅&lt;/strong>&lt;/p>&lt;p>可能很多人说起程序员，就会想到他们在周末根本不出门，躲在电脑后面刷动漫吧。&lt;/p>&lt;p>今年前半年有个妹纸在街头采访的时候回答了一个问题，突然爆红网络。当采访者问她，你觉得玩地下城的都是怎样一群人时，妹子笑着回答道：“我觉得他们都是一群死肥宅。”&lt;/p>&lt;p>于是，愤怒的“死肥宅”冲上街头，开着自己的宝马，穿上一身帅气西装，将头发梳成大人模样，包下了豪华网吧。&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>小编认为，比如“死宅”这个名词作为调侃或自嘲用用可以，但不要使用过度，否则就是对别人的攻击了，难免会伤了和气。很多程序员其实有丰富的业余生活的，可能刚入行时他们都特别忙碌。但这种忙碌的状态不可能一直都存在，等到他们闲下来的时候，其实生活还是很丰富多彩的。&lt;/p>&lt;p>&lt;strong>排名五：缺乏艺术细胞&lt;/strong>&lt;/p>&lt;p>很多人觉得程序员每天都是在进行枯燥的写代码检查bug的工作，但我们谁又没用他们辛苦做出来的产品呢？那些东西就是艺术，是他们思维和智慧的结晶，本身就是一个艺术品。&lt;/p>&lt;p>抛却这些东西不谈，他们能学会枯燥难懂的编程语言，自然就能学会其他的东西。&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>事实上，我身边的很多程序员都是多才多艺的，有人会弹吉他，有的拍过自己的微电影，有人是街舞高手。&lt;/p>&lt;p>他们是隐藏的高手，只不过深藏不露罢了。&lt;/p>&lt;p>&lt;strong>排名六：无趣&lt;/strong>&lt;/p>&lt;p>咪蒙说：“有趣是最好的解药”。&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>很多人千篇一律的重复着：“好看的皮囊千篇一律，有趣的灵魂万里挑一。”&lt;/p>&lt;p>我们都在叫嚷着有趣，似乎都不愿意承认自己的无趣。程序员这个群体，无趣这个标签算是坐实了很多年。因为工作的原因，他们的逻辑思维跟正常人的稍有不同，所以表现出十分无趣的表象。&lt;/p>&lt;p>但当你真正和他们接触之后就会发现，所谓的无趣都是偏见。因为他们会给你一些意想不到的惊喜，这里请自行脑补。&lt;/p>&lt;/div></description></item><item><title>IT程序员被叫“码农”程序员你怎么看？</title><link>https://pangyd.com/post/161-it/</link><pubDate>Wed, 08 Nov 2017 19:29:06 +0800</pubDate><guid>https://pangyd.com/post/161-it/</guid><description>&lt;p style="text-align: start">在几年之前，”码农“还只是行业内大家互相调侃的称谓，感觉现在几乎所有行业的人都喊IT工程师“码农”。“码农”反而成为了官方称呼了。感觉这不是一个好事，影响学生们对这个行业的看法，感觉好学校的学生都不愿意做技术了。技术大拿们该不该号召大家不要再以码农自称了？&lt;/p>&lt;p style="text-align: start">&lt;br>&lt;/p>&lt;p style="text-align: start">预料之内，这个话题引来众多程序员的讨论，下面摘选了10个比较有代（有）表（意）性（思）的回答：&lt;/p>&lt;p style="text-align: center">&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-size="700|569">&lt;/p>&lt;p style="text-align: justify">&lt;br>&lt;/p>&lt;p style="text-align: justify">&lt;span>程序员一：&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>歧视农名是不对的！&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>程序员二：&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>“码农”比“码畜”好听多了。&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>程序员三：&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>你多给我一倍薪水，叫我孙子都行。&lt;br>&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;br>&lt;/p>&lt;p style="text-align: justify">&lt;span>程序员四：&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>我们好歹还是人，产品和设计已经是狗了。&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;br>&lt;/p>&lt;p style="text-align: justify">&lt;span>程序员五：&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>码农算是好的，硅工是我等打磨芯片的民工的昵称。&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;br>&lt;/p>&lt;p style="text-align: justify">&lt;span>程序员六：&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>一位长者告诉我们“中国有句古话,叫做闷声发大财。”&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>程序员七：&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>这有什么？有些人还巴不得大家都说他是人民公仆呢。&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;br>&lt;/p>&lt;p style="text-align: justify">&lt;span>程序员八：&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>我们公司的美术还管我叫做“打字员”呢，满满的恶意啊&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>程序员九：&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>我们每天研究技术，哪有心思管这些，小屁孩们爱来不来。现在码农工资节节高升，正说明了人还不够。等人太多了，工资就会下跌，到时候我们就知道中国需要多少码农了。&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>程序员十：&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>一年工作经验的java程序员在北京可以拿到8k+以上（保守估计），码农通常智力都不低，少数码农有交际困难，不过多数都没有。这么一群高收入高智力的人群会被人鄙视？别闹了，我们只是自嘲而已，真的有哪个文科生来嘲笑我们，我们绝对会不择手段的在各个方面碾压过去的。trust me&lt;/span>&lt;/p></description></item><item><title>Java小技巧，从运行、控制到框架</title><link>https://pangyd.com/post/160-java/</link><pubDate>Wed, 08 Nov 2017 19:17:52 +0800</pubDate><guid>https://pangyd.com/post/160-java/</guid><description>&lt;p style="text-align: center">&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-size="657|493">&lt;/p>&lt;p style="text-align: start">&lt;span>1. JVM相关&lt;/span>&lt;/p>&lt;p style="text-align: start">&lt;span>JVM作为java运行的基础，很难相信对于JVM一点都不了解的人可以把java语言吃得很透。我在面试有超过3年Java经验的开发者的时候， JVM几乎就是一个必问的问题了。当然JVM不是唯一决定技术能力好坏的面试问题，但是可以佐证java开发能力的高低。&lt;/span>&lt;/p>&lt;p style="text-align: start">&lt;span>在JVM这个大类中，我认为需要掌握的知识有：&lt;/span>&lt;/p>&lt;p style="text-align: start">&lt;span>JVM内存模型和结构&lt;/span>&lt;/p>&lt;p style="text-align: start">&lt;span>GC原理，性能调优&lt;/span>&lt;/p>&lt;p style="text-align: start">&lt;span>调优：Thread Dump， 分析内存结构&lt;/span>&lt;/p>&lt;p style="text-align: start">&lt;span>class 二进制字节码结构， class loader 体系 ， class加载过程 ， 实例创建过程&lt;/span>&lt;/p>&lt;p style="text-align: start">&lt;span>方法执行过程&lt;/span>&lt;/p>&lt;p style="text-align: start">&lt;span>Java各个大版本更新提供的新特性(需要简单了解)&lt;/span>&lt;/p>&lt;p style="text-align: start">&lt;span>2. Java的运行（基础必备）&lt;/span>&lt;/p>&lt;p style="text-align: start">&lt;span>这个知识点是最最基本的java开发者需要掌握的，初学java，第一个肯定是教你如何在命令行中执行java程序，但是很多人一旦把java学完了，IDE用上了，就把这个都忘了。为什么强调要知道这个呢，知道了java最纯粹的启动方式之后，你才能在启动出问题的时候，去分析当时启动的目录多少，执行命名如何，参数如何，是否有缺失等。 这样有利于你真正开发中去解决那些奇奇怪怪的可能和环境相关的问题。&lt;/span>&lt;/p>&lt;p style="text-align: start">&lt;span>在这里需要掌握的知识有：&lt;/span>&lt;/p>&lt;p style="text-align: start">&lt;span>javac 编译java文件为 class 文件&lt;/span>&lt;/p>&lt;p style="text-align: start">&lt;span>java 命令的使用， 带package的java类如何在命令行中启动&lt;/span>&lt;/p>&lt;p style="text-align: start">&lt;span>java程序涉及到的各个路径(classpath， java。library。path， java运行的主目录等)&lt;/span>&lt;/p>&lt;p style="text-align: start">&lt;span>3. 数据类型&lt;/span>&lt;/p>&lt;p style="text-align: start">&lt;span>这条没有什么好多说的，无非就是Java中的基本类型和对象类型的掌握。可以再了解一些JDK如何自动转换方面的知识，包括装箱拆箱等，还要注意避免装箱之后的类型相等的判断&lt;/span>&lt;/p>&lt;p style="text-align: start">&lt;span>主要知识点：&lt;/span>&lt;/p>&lt;p style="text-align: start">&lt;span>基本类型： int， long， float， double， boolean ， 。。。&lt;/span>&lt;/p></description></item><item><title>Spring 知识点提炼</title><link>https://pangyd.com/post/159-spring/</link><pubDate>Tue, 07 Nov 2017 20:16:00 +0800</pubDate><guid>https://pangyd.com/post/159-spring/</guid><description>&lt;p>&lt;span>&lt;strong>1. Spring框架的作用&lt;/strong>&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;ul class="list-paddingleft-2">&lt;li>&lt;p>轻量：Spring是轻量级的，基本的版本大小为2MB&lt;/p>&lt;/li>&lt;li>&lt;p>控制反转：Spring通过控制反转实现了松散耦合，对象们给出它们的依赖，而不是创建或查找依赖的对象们。&lt;/p>&lt;/li>&lt;li>&lt;p>面向切面的编程AOP:Spring支持面向切面的编程，并且把应用业务逻辑和系统服务分开。&lt;/p>&lt;/li>&lt;li>&lt;p>容器：Spring包含并管理应用中对象的生命周期和配置&lt;/p>&lt;/li>&lt;li>&lt;p>MVC框架： Spring-MVC&lt;/p>&lt;/li>&lt;li>&lt;p>事务管理：Spring提供一个持续的事务管理接口，可以扩展到上至本地事务下至全局事务JTA&lt;/p>&lt;/li>&lt;li>&lt;p>异常处理：Spring提供方便的API把具体技术相关的异常&lt;/p>&lt;/li>&lt;/ul>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>&lt;strong>2. Spring的组成&lt;/strong>&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p style="text-align: center">&lt;img class="" title="20160512174600469" data-src="https://pangyd.com/uploads/2017/11/74c10f869f038762.jpg" data-ratio="0.518918918918919" data-w="555" data-type="gif" src="https://pangyd.com/uploads/2017/11/74c10f869f038762.jpg" data-fail="0">&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>Spring由7个模块组成：&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;ul class="list-paddingleft-2">&lt;li>&lt;p>Spring Core: 核心容器提供 Spring 框架的基本功能。核心容器的主要组件是BeanFactory，它是工厂模式的实现。BeanFactory 使用控制反转 （IOC） 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。&lt;/p>&lt;/li>&lt;li>&lt;p>Spring 上下文：Spring 上下文是一个配置文件，向 Spring 框架提供上下文信息。Spring 上下文包括企业服务，例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。&lt;/p>&lt;/li>&lt;li>&lt;p>Spring AOP：通过配置管理特性，Spring AOP 模块直接将面向方面的编程功能集成到了 Spring 框架中。所以，可以很容易地使 Spring 框架管理的任何对象支持 AOP。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP，不用依赖 EJB 组件，就可以将声明性事务管理集成到应用程序中。&lt;/p>&lt;/li>&lt;li>&lt;p>Spring DAO：JDBC DAO 抽象层提供了有意义的异常层次结构，可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理，并且极大地降低了需要编写的异常代码数量（例如打开和关闭连接）。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。&lt;/p>&lt;/li>&lt;li>&lt;p>Spring ORM：Spring 框架插入了若干个 ORM 框架，从而提供了 ORM 的对象关系工具，其中包括 JDO、Hibernate 和 iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。&lt;/p></description></item><item><title>JAVA的图案为什么是咖啡</title><link>https://pangyd.com/post/158-java/</link><pubDate>Mon, 06 Nov 2017 18:19:56 +0800</pubDate><guid>https://pangyd.com/post/158-java/</guid><description>&lt;p>&lt;br>&lt;/p>&lt;div class="content rich" data-reactid=".0.1.0.0.0.1.1.1">&lt;p style="text-align: center">&lt;span>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-size="603|434">&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;span>JAVA的图案为什么是咖啡？&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;span>在学习JAVA的时候&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;span>看到了JAVA的图案&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;span>是一杯咖啡&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;span>有没有好奇的呢？&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;span>有的话，我们一起来探讨探讨&lt;/span>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;/p>&lt;section class="">&lt;section>&lt;section>&lt;section class="">&lt;/section>&lt;/section>&lt;section style="text-align: center">&lt;section class="">&lt;section class="">&lt;span>第一个版本&lt;/span>&lt;/section>&lt;/section>&lt;/section>&lt;section class="">&lt;section class="">&lt;section class="" style="text-align: center">&lt;/section>&lt;/section>&lt;/section>&lt;section class="">&lt;section class="">&lt;section class="">&lt;/section>&lt;/section>&lt;/section>&lt;/section>&lt;/section>&lt;p>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>&lt;span>&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/span>&lt;span>&lt;span>&amp;nbsp;2000年度的&lt;/span>JavaOne&lt;span>国际会议大厅热闹非凡，一阵阵浓郁的咖啡味儿香气扑鼻。从世界各地汇集到旧金山参加会议的&lt;/span>Java&lt;span>精英们兴奋异常，排着长队，等待得到一杯由&lt;/span>Java&lt;span>语言控制的咖啡机煮制的免费咖啡。这是一个特殊设计的全透明咖啡机。当您按下按钮时，咖啡豆从玻璃管输送到研磨器。磨制后的咖啡粉由另一个玻璃管送到煮制机。沸腾的水滴入咖啡粉中，一杯醇香四溢的咖啡传送到您的手中…由此可见JAVA和咖啡有着不解之缘。&lt;/span>&lt;/span>&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;span>&lt;span>&lt;span>&lt;img data-src="https://pangyd.com/uploads/2017/11/74c10f869f038762.jpg" title="1711065214.jpg" class="" data-ratio="1.174731182795699" data-w="372" data-type="jpeg" width="286px" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-fail="0">&lt;/span>&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;/p>&lt;section class="">&lt;section>&lt;section>&lt;section class="">&lt;/section>&lt;/section>&lt;section style="text-align: center">&lt;section class="">&lt;section class="">第二个版本&lt;br>&lt;/section>&lt;/section>&lt;/section>&lt;section class="">&lt;section class="">&lt;section class="">&lt;/section>&lt;/section>&lt;/section>&lt;section class="">&lt;section class="">&lt;section class="">&lt;/section>&lt;/section>&lt;/section>&lt;/section>&lt;/section>&lt;p>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p style="text-align: justify">&lt;span>&lt;span>&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/span>&lt;span>最初这个为TV机顶盒所设计的语言在公司内部一直称为&lt;span>Green&lt;/span>项目。“我们的新语言需要一个名字。” 简姆斯&lt;span>.&lt;/span>古斯林一直在考虑这个问题。 有一天，简姆斯古斯林注意到自己办公室外一棵茂密的橡树&lt;span>Oak&lt;/span>，这是一种在硅谷很常见的树。所以他将这个新语言命名为&lt;span>Oak&lt;/span>。但&lt;span>Oak&lt;/span>是另外一个注册公司的名字。这个名字不可能再用了。如果通过正式程序来注册产品的名称将即费时又费钱。简姆斯古斯林决定通过市场部门，请来了一个命名顾问，召开命名征集会。当时，因为没有一个合适的名字，他们不得不延后这个语言的面世。&lt;span>在命名征集会上，大家提出了很多名字。最后按大家的评选次序，将十几个名字排列成表，上报给商标律师。排在第一位的是Silk（丝绸）。尽管大家都喜欢这个名字，但遭到简姆斯古斯林的坚决反对而作罢。排在第二和第三的都没有通过律师这一关。简姆斯古斯林最喜欢的就是排在第三位的&lt;/span>Lyric&lt;span>（抒情诗）。只有排在第四位的名字、得到了所有人的认可和律师的通过。这个名字就是&lt;/span>Java&lt;span>。&lt;/span>&lt;/span>&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>&lt;span>&lt;br>&lt;/span>&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;span>&lt;span>&lt;img data-src="https://pangyd.com/uploads/2017/11/74c10f869f038762.jpg" title="1711063382.jpg" class="" data-ratio="0.815" data-w="400" data-type="jpeg" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-fail="0">&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;/p>&lt;section class="">&lt;section>&lt;section>&lt;section class="">&lt;/section>&lt;/section>&lt;section style="text-align: center">&lt;section class="">&lt;section class="">&lt;span>第三个版本&lt;/span>&lt;/section>&lt;/section>&lt;/section>&lt;section class="">&lt;section class="">&lt;section class="">&lt;/section>&lt;/section>&lt;/section>&lt;section class="">&lt;section class="">&lt;section class="">&lt;br>&lt;/section>&lt;/section>&lt;/section>&lt;/section>&lt;/section>&lt;p>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/span>&lt;span>&lt;span>&lt;/span>还有一种说法是马克&amp;nbsp;奥颇门一家咖啡店与同事品尝咖啡时得到灵感的。Java是印度尼西亚爪哇岛的英文名称，因盛产咖啡而闻名。国外的许多咖啡店用Java来命名或宣传，以彰显其咖啡的品质。&lt;/span>&lt;/p>&lt;p>&lt;span>&amp;nbsp; &amp;nbsp; &amp;nbsp; Java语言中的许多库类名称，多与咖啡有关。JavaBeans（咖啡豆）、NetBeans（网络豆）以及ObjectBeans&amp;nbsp;（对象豆）等等。从此一个即好听又好记、具有强大的生命力的编程语言Java诞生了。&lt;/span>&lt;/p></description></item><item><title>Java小技巧，从运行、控制到框架</title><link>https://pangyd.com/post/157-java/</link><pubDate>Mon, 06 Nov 2017 18:19:27 +0800</pubDate><guid>https://pangyd.com/post/157-java/</guid><description>&lt;p style="text-align: center">&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-size="657|493">&lt;/p>&lt;p>&lt;span>1. JVM相关&lt;/span>&lt;/p>&lt;p>&lt;span>JVM作为java运行的基础，很难相信对于JVM一点都不了解的人可以把java语言吃得很透。我在面试有超过3年Java经验的开发者的时候， JVM几乎就是一个必问的问题了。当然JVM不是唯一决定技术能力好坏的面试问题，但是可以佐证java开发能力的高低。&lt;/span>&lt;/p>&lt;p>&lt;span>在JVM这个大类中，我认为需要掌握的知识有：&lt;/span>&lt;/p>&lt;p>&lt;span>JVM内存模型和结构&lt;/span>&lt;/p>&lt;p>&lt;span>GC原理，性能调优&lt;/span>&lt;/p>&lt;p>&lt;span>调优：Thread Dump， 分析内存结构&lt;/span>&lt;/p>&lt;p>&lt;span>class 二进制字节码结构， class loader 体系 ， class加载过程 ， 实例创建过程&lt;/span>&lt;/p>&lt;p>&lt;span>方法执行过程&lt;/span>&lt;/p>&lt;p>&lt;span>Java各个大版本更新提供的新特性(需要简单了解)&lt;/span>&lt;/p>&lt;p>&lt;span>2. Java的运行（基础必备）&lt;/span>&lt;/p>&lt;p>&lt;span>这个知识点是最最基本的java开发者需要掌握的，初学java，第一个肯定是教你如何在命令行中执行java程序，但是很多人一旦把java学完了，IDE用上了，就把这个都忘了。为什么强调要知道这个呢，知道了java最纯粹的启动方式之后，你才能在启动出问题的时候，去分析当时启动的目录多少，执行命名如何，参数如何，是否有缺失等。 这样有利于你真正开发中去解决那些奇奇怪怪的可能和环境相关的问题。&lt;/span>&lt;/p>&lt;p>&lt;span>在这里需要掌握的知识有：&lt;/span>&lt;/p>&lt;p>&lt;span>javac 编译java文件为 class 文件&lt;/span>&lt;/p>&lt;p>&lt;span>java 命令的使用， 带package的java类如何在命令行中启动&lt;/span>&lt;/p>&lt;p>&lt;span>java程序涉及到的各个路径(classpath， java。library。path， java运行的主目录等)&lt;/span>&lt;/p>&lt;p>&lt;span>3. 数据类型&lt;/span>&lt;/p>&lt;p>&lt;span>这条没有什么好多说的，无非就是Java中的基本类型和对象类型的掌握。可以再了解一些JDK如何自动转换方面的知识，包括装箱拆箱等，还要注意避免装箱之后的类型相等的判断&lt;/span>&lt;/p>&lt;p>&lt;span>主要知识点：&lt;/span>&lt;/p>&lt;p>&lt;span>基本类型： int， long， float， double， boolean ， 。。。&lt;/span>&lt;/p>&lt;p>&lt;span>对应的对象类型： Integer 等类型到基本类型的转换， 装箱和拆箱&lt;/span>&lt;/p>&lt;p>&lt;span>Object类型： equals， hashcode&lt;/span>&lt;/p>&lt;p>&lt;span>String 类型的特点&lt;/span>&lt;/p>&lt;p>&lt;span>4. 对象和实例，对象的创建&lt;/span>&lt;/p>&lt;p>&lt;span>在这方面，开发者需要了解class和instance的概念以及之间的差别， 这是java面向对象特性的一个基础。主要知识点有：&lt;/span>&lt;/p>&lt;p>&lt;span>Class和 Instance 的概念&lt;/span>&lt;/p>&lt;p>&lt;span>Instance 创建的过程：&lt;/span>&lt;/p></description></item><item><title>Java项目实战经验—程序员成长的钥匙</title><link>https://pangyd.com/post/156-java/</link><pubDate>Sun, 05 Nov 2017 19:49:28 +0800</pubDate><guid>https://pangyd.com/post/156-java/</guid><description>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>Java就是用来做项目的！Java的主要应用领域就是企业级的项目开发！要想从事企业级的项目开发，你必须掌握如下要点：&lt;/p>&lt;p>1、掌握项目开发的基本步骤&lt;/p>&lt;p>2、具备极强的面向对象的分析与设计技巧&lt;/p>&lt;p>3、掌握用例驱动、以架构为核心的主流开发方法&lt;/p>&lt;p>没有人愿意自己一辈子就满足于掌握了一些代码实现的技巧，别人告诉你要实现什么，你就用代码堆砌来实现别人的要求！你必须学会从整个项目的角度去思考！你必须学会假如你是项目经理，你该如何思考！你必须学会假如你是架构师，你该如何思考！你必须掌握针对某个特定问题领域的分析方法！&lt;/p>&lt;p>关于基础知识：你可以看看这些名词或知识点，看是否能说出个一二三四来。&lt;/p>&lt;p>JavaSE&lt;/p>&lt;p>----基本语法、数据类型、操作符等：int、long、Integer、Long、if、else、for、while&lt;/p>&lt;p>----面向对象：class（类）、Object（对象）、instance（实例）、state（状态）、behavior（行为）、field、method、new、可见性（访问控制）、attribute、property、package、import、static variable、class variable、instance variable、heap、method area、stack、GC（垃圾回收）、override、overload、对象转型(casting)、多态、this、super&lt;/p>&lt;p>----异常处理：理解编译期错误和运行期错误的区别、Exception、RuntimeException、checked exception、unchecked exception、try、catch、finally、throw new XXXException、throws XXXException、异常处理的基本原则&lt;/p>&lt;p>----数组与集合：数组的定义和使用方法、Collection、List、Set、Map、ArrayList、HashSet、HashMap、Iterator、equals、hashCode、Comparable、Comparator&lt;/p>&lt;p>----常用类：String、intern、常量池、StringBuffer、java.util.Date、SimpleDateFormat、Regex（正则表达式）&lt;/p>&lt;p>----反射机制：Class、Method、Field、invoke、newInstance、BeanUtils（apache-commons）、PropertyUtils（apache-commons）&lt;/p>&lt;p>----输入输出流：InputStream、OutputStream、Reader、Writer、Adapter设计模式与原始流类、Decorator设计模式与包装流类、对象序列化和反序列化&lt;/p>&lt;p>----多线程：Thread、Runnable、sleep、wait、notify、synchronized、lock&lt;/p>&lt;p>Servlet和JSP&lt;/p>&lt;p>----HttpServlet、doGet、doPost、HttpServletRequest、HttpServletResponse、request.getParameter()、request.setAttribute()、request.getAttribute()、request.getSession()、ServletContext、Filter、web.xml、tomcat、forward与redirect、http协议的无状态性、cookie、JSP Scope Object、、&lt;/p>&lt;p>HTML与JavaScript&lt;/p>&lt;p>----你需要能够理解常见的网页标签、理解在网页中引入JavaScript的方法、以及JavaScript的基本语法与使用方法&lt;/p>&lt;p>以上，就是你进一步学习Java所必备的基本知识。特别是一些个专业术语和名词，看到这些名词，如果你像看到亲爹一样亲切，那么说明你对Java的基础知识就很熟悉了。&lt;/p>&lt;p>接下来是SSH：&lt;/p>&lt;p>对于初学者来说，这三大框架被赋予了太多神秘的色彩，似乎它们是重中之重的知识！但是对于拥有多年Java开发经验的专业技术人员来说，对于那些Java牛人来说，却对这三大框架不太感冒！难道它们不重要吗？&lt;/p>&lt;p>现在很多企业都在用这三大框架，所以很多企业也把掌握这三大框架作为招聘的必备条件。不可否认的是，也有很多大型企业没有用这三大框架，这些企业经过多年发展，自身已经有一定的技术积累，也形成了自己独特的技术框架体系。这三大框架既可以说很重要，也可以说不重要。&lt;/p>&lt;p>说重要的原因在于：这三大框架对JavaEE开发中所存在的普遍的问题，提供了优美的解决方案，它们蕴含了这个行业中最NB的开发人员的努力和想法，所以，学习这三大框架，你就可以窥探到这些处于技术巅峰的牛人们究竟对一个问题是怎么想的，通过一种什么样的设计思路去解决问题的。所以，对于你来说，你没有太多项目开发的经验，经验是什么？经验就是你知道可能会遇到哪些问题，针对哪个问题可以有哪些解决方法，在某个情景下，哪种解决方法是较好的，哪种方法不太好等等！如果你没做过什么项目，你根本就不会去意识到你可能会遇到哪些问题，而这些问题往往又是非常关键的！解决得不好，会影响到你的程序的稳定性、可扩展性等等！三大框架就给初学者提供了了解你以后可能会遇到哪些问题，以及针对这些问题的解决方案！&lt;/p>&lt;p>当你了解了这三大框架为什么是重要的，那么你也就能理解，为什么这三大框架也可以说是不重要的。如果你曾经开发过很多项目，你碰到了各种各样的问题，凭着你的技术功底，逐个击破了这些问题，在这些人眼里，三大框架（是不是还有N个框架？呵呵）都是浮云！&lt;/p>&lt;p>你属于哪一种人呢？如果你没有太多项目开发经验，那么三大框架对于你来说就是非常重要的！而且，由此你也知道了该怎么去学这三大框架。对于三大框架的学习而言，着力点在于给你展示问题，并触发你自己主动的思考，我们鼓励你提出自己的想法，也许你的想法很白痴，但那毕竟是你自己的想法，如果你不知道牛人的想法，那你怎么知道自己的想法是很白痴的呢？在这种思想的碰撞过程中，你就会逐渐提高自己！所以，三大框架学完之后，你不应该只是看到一大堆配置文件，你不应该只是看到了一些Action，一些Service，一些映射文件，你不应该只知道session.save/update/delete，你不应该只是知道struts2中有一堆interceptor，你不应该只是看到一堆jar包……&lt;/p>&lt;p>如果你只是知道拷贝一堆jar包，定义一系列配置文件之后，SSH三大框架就能够运行起来了，也可以给你干活了，那么，很悲哀的是，你仍然没有掌握三大框架的精粹！请你回答以下问题：&lt;/p>&lt;p>Struts2：&lt;/p>&lt;p>为什么每次请求都要创建一个Action对象？&lt;/p>&lt;p>ModelDriven拦截器的配置中refreshModelBeforeResult解决了什么问题？&lt;/p>&lt;p>为什么在web.xml中配置的StrutsPrepareAndExecuteFilter要过滤所有的请求？&lt;/p>&lt;p>请你给我谈谈ValueStack？&lt;/p>&lt;p>Struts2是如何实现MVC设计模式的？&lt;/p>&lt;p>Spring：&lt;/p>&lt;p>你为什么要用Spring？&lt;/p>&lt;p>请你聊一聊IOC/DI？&lt;/p>&lt;p>什么是声明式的事务管理？为什么要使用声明式的事务管理？Spring如何实现声明式的事务管理？&lt;/p>&lt;p>把spring和hibernate集成，定义事务管理特性的时候，为何要将除了添加、删除、更新操作之外的方法，即主要执行查询任务的方法定义为read-only？&lt;/p>&lt;p>Hibernate：&lt;/p>&lt;p>请你谈谈你对OR映射的理解？&lt;/p>&lt;p>很多人说Hibernate不适合大项目，性能有问题，你是如何理解的？&lt;/p>&lt;p>Hibernate为什么一定要定义一个数据库标识？&lt;/p>&lt;p>为什么Hibernate建议你的实体类实现hashCode和equals方法？&lt;/p>&lt;p>谈谈你对Hibernate实体类中的数据库标识与数据库主键之间关系的认识？&lt;/p>&lt;p>谈谈你对Hibernate关联映射与数据库外键之间关系的认识？&lt;/p>&lt;p>调用session.save()方法，hibernate一定会发出insert语句吗？谈谈你的理解&lt;/p>&lt;p>调用session.update()方法，hibernate一定会发出update语句吗？谈谈你的理解&lt;/p>&lt;p>请你聊一下以下名词、概念或用法：lazy、lazy=”extra”、inverse、fetch、fetch=”join”、fetch=”subselect”、batch-size&lt;/p>&lt;p>配置了lazy=”true”一定会实现懒加载吗？&lt;/p>&lt;p>请你谈谈Hibernate中的“N 1”问题&lt;/p>&lt;p>请你谈谈Hibernate有哪些最佳实践？&lt;/p>&lt;p>以上并非SSH中全部重点的问题，但它们能考察你能否灵活运用SSH框架！如果你能深刻理解这些问题，再配以合适的实战项目训练，你也会逐渐成为牛人！&lt;/p>&lt;p>最后是项目开发能力：&lt;/p>&lt;p>不管你是学Java还是别的技术，你的根本目的在于给客户创造价值！否则，你下大力气学习的东西，随着技术的进步和更新，很快就会过时！所以，技术的核心在于用技术创造有价值的成果！也就是说，客户需要什么，你就要用技术把客户需要的东西给他造出来！一个公司之所以要用各种福利条件极力挽留你，是因为你能够给公司带来极高的利益！那么，你有什么可以给公司利用的呢？公司最看重你的哪方面的能力呢？&lt;/p></description></item><item><title>Web前端知识体系精简</title><link>https://pangyd.com/post/155-web/</link><pubDate>Sun, 05 Nov 2017 19:28:29 +0800</pubDate><guid>https://pangyd.com/post/155-web/</guid><description>&lt;p>&lt;span>Web前端技术由html、CSS和JavaScript三大部分构成，是一个庞大而复杂的技术体系，其复杂程度不低于任何一门后端语言。而我们在学习它的时候往往是先从某一个点切入，然后不断地接触和学习新的知识点，因此对于初学者很难理清楚整个体系的脉络结构。&lt;span>本文将对Web前端知识体系进行简单的梳理&lt;/span>，对应的每个知识点点到为止，不作详细介绍。目的是帮助大家审查自己的知识结构是否完善，如有遗漏或不正确的地方，希望共勉。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br data-filtered="filtered">&lt;/span>&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-size="640|360">&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;h3>&lt;span>&lt;span>JAVASCRIPT 篇&lt;/span>&lt;/span>&lt;/h3>&lt;h3>&lt;span>&lt;br data-filtered="filtered">&lt;/span>&lt;/h3>&lt;h3>&lt;span>&lt;span>0、基础语法&lt;/span>&lt;/span>&lt;/h3>&lt;p>&lt;span>&lt;br data-filtered="filtered">&lt;/span>&lt;/p>&lt;p>&lt;span>Javascript基础语法包括：变量定义、数据类型、循环、选择、内置对象等。&lt;/span>&lt;/p>&lt;p>&lt;span>数据类型有string,number,boolean,null,undefined,object等。其中，string,number和boolean是基础类型,null和undefined是JS中的两个特殊类型,object是引用类型。 &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/span>&lt;/p>&lt;p>&lt;span>Javascript可以通过typeof来判断基础数据类型，但不能够准确判断引用类型, 因此需要用到另外一个方法，那就是Object的toString,&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br data-filtered="filtered">&lt;/span>&lt;/p>&lt;p>&lt;span>JS常用的内置对象有Date、Array、JSON,RegExp等。 一般来讲，Date和Array用的最频繁，JSON可以对对象和数组进行序列化和反序列化，还有一个作用就是实现对象的深拷贝。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br data-filtered="filtered">&lt;/span>&lt;/p>&lt;p>&lt;span>RegExp即正则表达式，是处理字符串的利器。&amp;nbsp;&lt;/span>&lt;/p>&lt;h4>&lt;span>&lt;br data-filtered="filtered">&lt;/span>&lt;/h4>&lt;h4>&lt;span>&lt;span>1、函数原型链&lt;/span>&lt;/span>&lt;/h4>&lt;p>&lt;span>&lt;br data-filtered="filtered">&lt;/span>&lt;/p>&lt;p>&lt;span>Javascript虽然没有继承概念，但Javascript在函数Function对象中建立了原型对象prototype，并以Function对象为主线，从上至下，在内部构建了一条原型链。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br data-filtered="filtered">&lt;/span>&lt;/p>&lt;p>&lt;span>简单来说就是建立了变量查找机制，当访问一个对象的属性时，先查找对象本身是否存在，如果不存在就去该对象所在的原型连上去找，直到Object对象为止，如果都没有找到该属性才会返回undefined。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br data-filtered="filtered">&lt;/span>&lt;/p>&lt;p>&lt;span>因此我们经常会利用函数的原型机制来实现JS继承。&lt;/span>&lt;/p>&lt;p>&lt;br data-filtered="filtered">&lt;/p>&lt;h4>&lt;span>&lt;span>2、函数作用域&lt;/span>&lt;/span>&lt;/h4>&lt;p>&lt;span>&lt;br data-filtered="filtered">&lt;/span>&lt;/p>&lt;p>&lt;span>函数作用域就是变量在声明它们的函数体以及这个函数体嵌套的任意函数体内都是有定义的。在JS中没有会块级作用域，只有函数作用域，因此JS中还存在着另外一种怪异现象，那就是变量提升。&lt;/span>&lt;/p>&lt;p>&lt;br data-filtered="filtered">&lt;/p>&lt;h4>&lt;span>&lt;span>3、函数指针 this&lt;/span>&lt;/span>&lt;/h4>&lt;p>&lt;span>&lt;br data-filtered="filtered">&lt;/span>&lt;/p>&lt;p>&lt;span>this 存在于函数中，它指向的是该函数在运行时被调用的那个对象。在实际项目中，遇到this的坑比较多，因此需要对this作深入的理解。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br data-filtered="filtered">&lt;/span>&lt;/p>&lt;p>&lt;span>Function对象还提供了call、apply和bind等方法来改变函数的this指向，其中call和apply主动执行函数，bind一般在事件回调中使用，而call和apply的区别只是参数的传&lt;/span>&lt;/p>&lt;p>&lt;span>递方式不同。&lt;/span>&lt;/p>&lt;h4>&lt;span>&lt;br data-filtered="filtered">&lt;/span>&lt;/h4>&lt;h4>&lt;span>&lt;span>4、构造函数 new&lt;/span>&lt;/span>&lt;/h4>&lt;p>&lt;span>&lt;br data-filtered="filtered">&lt;/span>&lt;/p>&lt;p>&lt;span>JS中的函数即可以是构造函数又可以当作普通函数来调用，当使用new来创建对象时，对应的函数就是构造函数，通过对象来调用时就是普通函数。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br data-filtered="filtered">&lt;/span>&lt;/p>&lt;p>&lt;span>普通函数的创建有：显式声明、匿名定义、new Function() 等三种方式。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br data-filtered="filtered">&lt;/span>&lt;/p>&lt;p>&lt;span>当通过new来创建一个新对象时，JS底层将新对象的原型链指向了构造函数的原型对象，于是就在新对象和函数对象之间建立了一条原型链，通过新对象可以访问到函数对象原型prototype中的方法和属性。&lt;/span>&lt;/p>&lt;p>&lt;br data-filtered="filtered">&lt;/p>&lt;h4>&lt;span>&lt;span>5、闭包&lt;/span>&lt;/span>&lt;/h4>&lt;p>&lt;span>&lt;br data-filtered="filtered">&lt;/span>&lt;/p></description></item><item><title>15张脑图看懂 Python 编程核心知识体系</title><link>https://pangyd.com/post/154-15-python/</link><pubDate>Sat, 04 Nov 2017 22:27:14 +0800</pubDate><guid>https://pangyd.com/post/154-15-python/</guid><description>&lt;p>首先，按顺序依次展示了以下内容的一系列思维导图：基础知识，数据类型（数字，字符串，列表，元组，字典，集合），条件&amp;amp;循环，文件对象，错误&amp;amp;异常，函数，模块，面向对象编程；&lt;/p>&lt;p>接着，结合这些思维导图主要参考的资料，分享一下我的学习体验，一方面可供初学者参考，另一方面，也便于大家结合思维导图深入学习、理解、思考；&lt;/p>&lt;p>最后，提供几篇文章链接，方便希望从 Python 2.x 迁移到 3.x 的朋友理解。&lt;/p>&lt;p>编程是这样一件美妙的事情，如果你没有开始，你不知道会错过一种多么棒的体验。Just try it~和大家共勉！&lt;/p>&lt;p>注意事项：&lt;/p>&lt;p>思维导图：&lt;/p>&lt;p>默认阅读顺序：从右左，顺时针方向。&lt;/p>&lt;p>思维导图软件：XMind&lt;/p>&lt;p>总览：&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-size="1000|896">&lt;/p>&lt;p>14 张思维导图基础知识&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-size="1000|603">&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-size="1000|695">&lt;/p>&lt;p>数据类型&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-size="640|421">&lt;/p>&lt;p>&lt;/p>&lt;p>序列&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-size="640|856">&lt;/p>&lt;p>字符串&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-size="1000|734">&lt;/p>&lt;p>列表 &amp;amp; 元组&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-size="640|286">&lt;/p>&lt;p>字典 &amp;amp; 集合&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-size="640|376">&lt;/p>&lt;p>条件 &amp;amp; 循环&lt;/p></description></item><item><title>java多线程高级教程，这些你都懂了吗？</title><link>https://pangyd.com/post/153-java/</link><pubDate>Thu, 02 Nov 2017 23:21:04 +0800</pubDate><guid>https://pangyd.com/post/153-java/</guid><description>&lt;p>一、countdownLatch和cyclicbarrier（这两个做多线程控制很好用，工作中会经常用到）&lt;/p>&lt;p>countdownLatch：主线程阻塞，当多个线程countdown到0，主线程执行；&lt;/p>&lt;p>cyclicbarrier：多个线程等待，当都处于等待状态了一起执行（类似于赛跑机制）&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" img_width="641" img_height="517" alt="java多线程高级教程，这些你都懂了吗？" inline="0">&lt;/p>&lt;p class="pgc-img-caption" style="text-align: center">countdownLatch&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" img_width="677" img_height="385" alt="java多线程高级教程，这些你都懂了吗？" inline="0">&lt;/p>&lt;p class="pgc-img-caption" style="text-align: center">cyclicbarrier&lt;br>&lt;/p>&lt;p>二、volatile和threadlocal&lt;/p>&lt;p>这两个也要很好掌握，不仅常用，而且面试时候也经常问到！&lt;/p>&lt;p>volatile:使属性可见性。有个属性是共享属性，这个关键字会在每个线程内开一块内存，每次子线程都会从主线程拿最新的属性放到内存中。但是有个问题，他只是拿最新的，比如：计数器，每个线程都执行+1操作。一个线程+1，另外两个同时读取这个属性，那么不会加2次，而是只加一次，这就是valatile不能保证原子性的原因。&lt;/p>&lt;p>threadlocal：用于做方法外的全局属性。这个跟volatile刚好相反，使全局变量独立，每个线程里都有一份独立副本。&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" img_width="770" img_height="261" alt="java多线程高级教程，这些你都懂了吗？" inline="0">&lt;/p>&lt;p>这是hibernate的源码，如果当前线程没有session就openSession放到ThreadLocalMap中，每个线程的session都是独立的不会相互受影响。&lt;/p>&lt;p>三、AtomicInteger：支持原子性计数器。&lt;/p>&lt;p>之前说volatile不能作为计数器，那么多线程计数器要用atomic类的AtomicInteger&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" img_width="977" img_height="576" alt="java多线程高级教程，这些你都懂了吗？" inline="0">&lt;/p>&lt;p>四、并发类容器&lt;br>&lt;/p>&lt;p>ConCurrentHashMap、CopyAndWriteArrayList、CopyAndWriteArraySet。&lt;/p>&lt;p>ConCurrentHashMap（底层分成16个hashtable来保证并发）读支持高并发读，写和删除时候只支持16个线程，所以一般也要上锁； copyandwrite支持高并发读，写的话要加锁（原理是，写的时候赋值一个容器，写好了把指针指向新容器并且删除原容器）&lt;/p>&lt;p>map、list、set都有并发类容器。面试时候经常会问hashmap和ConCurrentHashMap区别。这个demo我就不写了，用法和我们平时用的集合都一样，只是他们不会造成线程不安全。&lt;/p>&lt;p>五、并发类队列&lt;/p>&lt;p>阻塞的意思是，当达到队列最大容量或者为空，线程还往里加东西或取东西会被阻塞；有界意思，可以设置队列大小。&lt;/p>&lt;p>（非阻塞队列）ConcurrentLinkedQueue无阻塞无界限队列（高并发性能最好，peek取出不删除，poll取出删除），&lt;/p>&lt;p>（阻塞队列）ArrayBlockingQueue阻塞有界队列，LinkBlockingQueue阻塞无界队列（生产者消费者首选，take方法会阻塞，poll方法没有就返回null）。&lt;/p>&lt;p>这里我们以最经典的生产者消费者模式作为例子&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" img_width="966" img_height="741" alt="java多线程高级教程，这些你都懂了吗？" inline="0">&lt;/p>&lt;p>这里我们顺便做一个延伸，我们用的所有线程池，包括面试时候经常问的要你自定义一个线程池怎么做？我们先看一下线程池的源码。&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" img_width="812" img_height="153" alt="java多线程高级教程，这些你都懂了吗？" inline="0">&lt;/p>&lt;p>也就是说线程池也是用并发队列作为线程的容器。我们自定义时候也只需要重现实例化ThreadPoolExcutor，设置我们自己需要的参数即可。&lt;br>&lt;/p>&lt;p>六、分布式锁&lt;br>&lt;/p>&lt;p>这个其实已经不属于java代码范畴，但是我上一篇讲基础的时候，一些兄弟说我说的太简单，另一些又说太难，所以我加了一个分布式锁，希望能满足更多人需求。&lt;/p>&lt;p>分布式锁，主要用在分布式集群上，既然是分布式，那就有多个jvm，即使你代码写出花来也不能控制。所以只有一个办法就是借助第三方工具。比如memcache、redis、zk&lt;/p>&lt;p>1. 首先明确一点，有人可能会问是否可以考虑采用ReentrantLock来实现，但是实际上去实现的时候是有问题的，ReentrantLock的lock和unlock要求必须是在同一线程进行，而分布式应用中，lock和unlock是两次不相关的请求，因此肯定不是同一线程，因此导致无法使用ReentrantLock。&lt;/p>&lt;p>2. 基于数据库表做乐观锁，用于分布式锁。&lt;/p>&lt;p>3. 使用memcached的add()方法，用于分布式锁。&lt;/p></description></item><item><title>Java入门学习进阶知识点汇总</title><link>https://pangyd.com/post/152-java/</link><pubDate>Wed, 01 Nov 2017 20:04:15 +0800</pubDate><guid>https://pangyd.com/post/152-java/</guid><description>&lt;p style="text-align: left">&lt;span style="text-align: justify">入门阶段，主要是培养Java语言的编程思想。了解Java语言的语法，书写规范等，掌握Eclipse、MyEclipse等开发工具，编写Java代码的能力。学完这个阶段你应该可进行小型应用程序开发并且可以对数据库进行基本的增删改查管理。&lt;/span>&lt;/p>&lt;p style="text-align: left">&lt;strong style="text-align: justify">&lt;span>注意：&lt;/span>&lt;/strong>&lt;span style="text-align: justify">此阶段知识点的学习，需要真实的项目进行驱动学习，让你轻松理解各知识点。&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;span>&lt;/span>&amp;nbsp;&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-size="638|404">&lt;/p>&lt;p style="text-align: justify">&lt;span>&lt;strong>1 计算机基础知识&lt;/strong>&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>&amp;nbsp;&lt;span>针对零基础学习的人，从对计算机操作等知识的了解，延伸到Java语言的发展与开发工具的使用上。主要是了解怎样执行计算机命令，认识Java这门语言，感受编程语言Java怎么开发程序。&lt;/span>&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;strong>&lt;span>(1)&amp;nbsp;计算机基础&lt;/span>&lt;/strong>&lt;/p>&lt;p style="text-align: justify">&lt;span>零基础学习的人先了解计算机相关知识，进而再去了解Java语言。&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;strong>&lt;span>(2)&amp;nbsp;DOS常用命令&lt;/span>&lt;/strong>&lt;/p>&lt;p style="text-align: justify">&lt;span>了解什么是DOS，并掌握DOS控制台的打开方式，同时熟悉常用的DOS命令，例如：盘符切换、进入指定目录、删除文件等，完成使用DOS命令对计算机进行操作和控制。&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;strong>&lt;span>(3)&amp;nbsp;Java概述&lt;/span>&lt;/strong>&lt;/p>&lt;p style="text-align: justify">&lt;span>了解Java语言的发展史、Java语言平台版本、Java语言的特点，以及JRE与JDK。JRE是Java的运行环境，JDK是Java开发工具包，它包含了Java的开发工具以及JRE。所以安装了JDK就不用再单独安装JRE了。&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;strong>&lt;span>(4)&amp;nbsp;JDK环境安装配置&lt;/span>&lt;/strong>&lt;/p>&lt;p style="text-align: justify">&lt;span>了解了什么是JDK，以及JDK的重要性，下一步我们就来学习如何安装和配置JDK环境。在安装JDK之前，我们首先需要下载JDK，针对不同的系统，我们需要下载不用版本的JDK。&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;strong>&lt;span>(5)&amp;nbsp;环境变量配置&lt;/span>&lt;/strong>&lt;/p>&lt;p style="text-align: justify">&lt;span>了解path、classpath环境变量，理解path变量和classpath变量的作用，并掌握path变量和classpath变量的配置方式。&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;strong>&lt;span>(6)&amp;nbsp;Java程序入门&lt;/span>&lt;/strong>&lt;/p>&lt;p style="text-align: justify">&lt;span>当JDK、环境变量配置完毕，我们就可以开始&amp;nbsp;编写Java程序。编写Java程序可以使用如下几种工具：notepad（微软操作系统自带）、Editplus、Notepad++、Eclipse、MyEclipse。&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>&lt;/span>&amp;nbsp;&lt;/p>&lt;p style="text-align: justify">&lt;span>&lt;strong>&amp;nbsp;&lt;span>2 编程基础&lt;/span>&lt;/strong>&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>&amp;nbsp;&lt;span>此模块学习主要是了解编程的具体流程，学习Java基础语法的格式等。具体要掌握不同数据类型的变量定义与使用，掌握不同运算符的运算规则，掌握流程控制语句的执行流程，编写方法的声明与调用，创建数组并访问数组元素等知识。&lt;/span>&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;strong>&lt;span>&amp;nbsp;&lt;span>(1)&amp;nbsp;注释&lt;/span>&lt;/span>&lt;/strong>&lt;/p>&lt;p style="text-align: justify">&lt;span>在程序开发工程中，用于解释和说明程序的文字我们称之为注释，Java中的注释分为以下几种：单行注释、多行注释、文档注释。&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;strong>&lt;span>&amp;nbsp;&lt;span>(2)&amp;nbsp;关键字&lt;/span>&lt;/span>&lt;/strong>&lt;/p>&lt;p style="text-align: justify">&lt;span>了解Java关键字的含义及特点，掌握关键字使用的注意事项。&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;strong>&lt;span>( &lt;span>3)&amp;nbsp;标识符&lt;/span>&lt;/span>&lt;/strong>&lt;/p>&lt;p style="text-align: justify">&lt;span>了解什么是标识符，标识符的组成规则，以及标识符使用时的注意事项。&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;strong>&lt;span>( &lt;span>4)&amp;nbsp;常量与变量&lt;/span>&lt;/span>&lt;/strong>&lt;/p>&lt;p style="text-align: justify">&lt;span>理解常量与变量的含义，并掌握常量与变量的区别、变量的定义格式以及变量的赋值。&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;strong>&lt;span>( &lt;span>5)&amp;nbsp;数据类型&lt;/span>&lt;/span>&lt;/strong>&lt;/p>&lt;p style="text-align: justify">&lt;span>掌握Java语言的数据类型，如基本数据类型：byte、short、int、long、float、double、char、boolean，以及引用类型：类、接口、数组。&lt;/span>&lt;/p></description></item><item><title>Java数据结构与算法</title><link>https://pangyd.com/post/151-java/</link><pubDate>Tue, 31 Oct 2017 18:25:34 +0800</pubDate><guid>https://pangyd.com/post/151-java/</guid><description>&lt;p>&lt;br>&lt;/p>&lt;div class="userinfo" data-reactid=".1jh8s1a0g74.1.0.0.0.1.1.0">&lt;span class="username" data-reactid=".1jh8s1a0g74.1.0.0.0.1.1.0.0">Cany&lt;/span>&lt;span class="male" data-reactid=".1jh8s1a0g74.1.0.0.0.1.1.0.1">&lt;/span>&lt;span data-reactid=".1jh8s1a0g74.1.0.0.0.1.1.0.2">&lt;span class="honour admin" data-reactid=".1jh8s1a0g74.1.0.0.0.1.1.0.2.$admin">大酋长&lt;/span>&lt;/span>&lt;/div>&lt;div class="content rich" data-reactid=".1jh8s1a0g74.1.0.0.0.1.1.1">&lt;p>&lt;span>刚学习数据结构与算法时，就被告知&lt;span>&amp;nbsp;“程序=算法+数据结构”&lt;/span>，而这段话来自于对点计算机科学家Niklaus Wirth在1976年出版的一本书的书名，后来这句话也成为计算机工作者之间流传的一句名言，小编也用惨痛的经历告诉大家这也是一个很重要的知识点。&lt;/span>&lt;/p>&lt;p>&lt;span>&amp;nbsp;&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;img data-s="300,640" data-type="jpeg" data-src="https://pangyd.com/uploads/2017/10/74c10f869f038762.jpg" data-copyright="0" class="" data-ratio="1.0909090909090908" data-w="110" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-fail="0">&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;br>&lt;/p>&lt;p>&lt;span>&lt;span>那么到底什么是数据结构和算法，数据结构算法又有什么用呢？&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>首先来说说什么是数据结构，直接上图&lt;/span>&lt;/p>&lt;p>&lt;span>&amp;nbsp;&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;img data-s="300,640" data-type="jpeg" data-src="https://pangyd.com/uploads/2017/10/74c10f869f038762.jpg" data-copyright="0" class="" data-ratio="0.59613196814562" data-w="879" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-fail="0">&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;br>&lt;/p>&lt;p>&lt;span>从图中我们可以很直观的看出数据结构涵盖的内容。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>算法的介绍就相对抽象了，百度百科给出的解释是&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>算法是对特定问题求解步骤的一种描述，它是指令的有限序列，其中每一条指令表示一个或者多个操作。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>但是我们从他的特性来理解就会简单多了。&lt;span>算法主要有五个特性&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>· 有穷性：指令序列是有限的&lt;/span>&lt;/p>&lt;p>&lt;span>· 确定性：每条语句的含义明确，无二义性&lt;/span>&lt;/p>&lt;p>&lt;span>· 可行性：每条语句都应在有限的时间内完成&lt;/span>&lt;/p>&lt;p>&lt;span>· 输入：零个或者多个输入&lt;/span>&lt;/p>&lt;p>&lt;span>· 输出：一个或者多个输出&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;img data-s="300,640" data-type="jpeg" data-src="https://pangyd.com/uploads/2017/10/74c10f869f038762.jpg" data-copyright="0" class="" data-ratio="0.8" data-w="1280" width="328px" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-fail="0">&lt;/p></description></item><item><title>Java在各个操作系统中的安装方式</title><link>https://pangyd.com/post/150-java/</link><pubDate>Mon, 30 Oct 2017 17:43:48 +0800</pubDate><guid>https://pangyd.com/post/150-java/</guid><description>&lt;p>&lt;br>&lt;/p>&lt;div class="content rich" data-reactid=".1colohowohs.1.0.0.0.1.1.1">&lt;p>&lt;span>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" img_width="640" img_height="360" alt="java逆天攻略：快速进入大数据开发核心技术" inline="0">&lt;/span>&lt;/p>&lt;p>&lt;span>前言&lt;/span>&lt;/p>&lt;p>&lt;span>Java安装应该是件非常简单的事情，不知何时在Oracle官方下载JDK时，竟然强制要求用户登陆。这样就不能通过Linux命令wget下载了，真是有点让人火大。&lt;/span>&lt;/p>&lt;p>&lt;span>想了个办法破解这种恶心的cookies验证行为！&lt;/span>&lt;/p>&lt;blockquote>&lt;p>&lt;span>对大数据感兴趣的朋友可以加群大数据视频学习交流群 675590728&lt;/span>&lt;/p>&lt;/blockquote>&lt;p>&lt;span>目录&lt;/span>&lt;/p>&lt;ul class=" list-paddingleft-2">&lt;li>&lt;p>&lt;span>Java在Windows中安装&lt;/span>&lt;/p>&lt;/li>&lt;li>&lt;p>&lt;span>Java在Linux Ubuntu中安装&lt;/span>&lt;/p>&lt;/li>&lt;/ul>&lt;p>&lt;span>1 Java在Windows中安装&lt;/span>&lt;/p>&lt;p>&lt;span>Java环境安装，是指Java开发环境的安装，包括JDK安装和Java的环境配置。在Windows中，很多的Java应用通过JRE就可以运行。但对Java的开发者来说，我们需要安装JDK，必须Oracle SUN官方发布的JDK。&lt;/span>&lt;/p>&lt;blockquote>&lt;p>&lt;span>在Windows系统上安装JDK是件非常简单的事情，对大数据感兴趣的朋友可以加群大数据视频学习交流群 675590728&lt;/span>&lt;/p>&lt;/blockquote>&lt;p>&lt;span>大家可以下载最新版本的Java SE 8，或者较早的JDK版本。本文中使用的是1.6.0_45版本的JDK。&lt;/span>&lt;/p>&lt;p>&lt;span>下载后，双击安装。我安装在目录: D:	oolkitjavajdk6&lt;/span>&lt;/p>&lt;p>&lt;span>安装好JDK后，配置环境变量：&lt;/span>&lt;/p>&lt;p>&lt;span>选择：控制面板 –&amp;gt; 系统和安全 –&amp;gt; 系统属性 –&amp;gt; 高级 –&amp;gt; 环境变量&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" img_width="821" img_height="720" alt="java逆天攻略：快速进入大数据开发核心技术" inline="0">&lt;/span>&lt;/p>&lt;pre>#&amp;nbsp;新建JAVA_HOME变量JAVA_HOME=D:	oolkitjavajdk6#&amp;nbsp;新建PATH变量PATH=D:&amp;nbsp;oolkitjavajdk6in&lt;/pre>&lt;p>&lt;span>注：如果PATH变量已存在，则在最后增加JDK的路径，用分号(;)与上个配置做分隔。&lt;/span>&lt;/p>&lt;p>&lt;span>保存后，打开CMD命令窗口，测试Java的命令行操作。&lt;/span>&lt;/p>&lt;pre>#&amp;nbsp;查看Java安装版本~&amp;nbsp;C:UsersAdministrator&amp;gt;java&amp;nbsp;-versionjava&amp;nbsp;version&amp;nbsp;"1.6.0_45"Java(TM)&amp;nbsp;SE&amp;nbsp;Runtime&amp;nbsp;Environment&amp;nbsp;(build&amp;nbsp;1.6.0_45-b06)Java&amp;nbsp;HotSpot(TM)&amp;nbsp;64-Bit&amp;nbsp;Server&amp;nbsp;VM&amp;nbsp;(build&amp;nbsp;20.45-b01,&amp;nbsp;mixed&amp;nbsp;mode)#&amp;nbsp;测试Java命令~&amp;nbsp;C:UsersAdministrator&amp;gt;javaUsage:&amp;nbsp;java&amp;nbsp;[-options]&amp;nbsp;class&amp;nbsp;[args...]&amp;nbsp;(to&amp;nbsp;execute&amp;nbsp;a&amp;nbsp;class)&amp;nbsp;or&amp;nbsp;java&amp;nbsp;[-options]&amp;nbsp;-jar&amp;nbsp;jarfile&amp;nbsp;[args...]&amp;nbsp;(to&amp;nbsp;execute&amp;nbsp;a&amp;nbsp;jar&amp;nbsp;file)where&amp;nbsp;options&amp;nbsp;include:&amp;nbsp;-server&amp;nbsp;to&amp;nbsp;select&amp;nbsp;the&amp;nbsp;"server"&amp;nbsp;VM&amp;nbsp;-hotspot&amp;nbsp;is&amp;nbsp;a&amp;nbsp;synonym&amp;nbsp;for&amp;nbsp;the&amp;nbsp;"server"&amp;nbsp;VM&amp;nbsp;[deprecated]&amp;nbsp;The&amp;nbsp;default&amp;nbsp;VM&amp;nbsp;is&amp;nbsp;server.&amp;nbsp;-cp-classpathA&amp;nbsp;;&amp;nbsp;separated&amp;nbsp;list&amp;nbsp;of&amp;nbsp;directories,&amp;nbsp;JAR&amp;nbsp;archives,&amp;nbsp;and&amp;nbsp;ZIP&amp;nbsp;archives&amp;nbsp;to&amp;nbsp;search&amp;nbsp;for&amp;nbsp;class&amp;nbsp;files.&amp;nbsp;-D=set&amp;nbsp;a&amp;nbsp;system&amp;nbsp;property&amp;nbsp;-verbose[:class|gc|jni]&amp;nbsp;enable&amp;nbsp;verbose&amp;nbsp;output&amp;nbsp;-version&amp;nbsp;print&amp;nbsp;product&amp;nbsp;version&amp;nbsp;and&amp;nbsp;exit&amp;nbsp;-version:require&amp;nbsp;the&amp;nbsp;specified&amp;nbsp;version&amp;nbsp;to&amp;nbsp;run&amp;nbsp;-showversion&amp;nbsp;print&amp;nbsp;product&amp;nbsp;version&amp;nbsp;and&amp;nbsp;continue&amp;nbsp;-jre-restrict-search&amp;nbsp;|&amp;nbsp;-jre-no-restrict-search&amp;nbsp;include/exclude&amp;nbsp;user&amp;nbsp;private&amp;nbsp;JREs&amp;nbsp;in&amp;nbsp;the&amp;nbsp;version&amp;nbsp;search&amp;nbsp;-?&amp;nbsp;-help&amp;nbsp;print&amp;nbsp;this&amp;nbsp;help&amp;nbsp;message&amp;nbsp;-X&amp;nbsp;print&amp;nbsp;help&amp;nbsp;on&amp;nbsp;non-standard&amp;nbsp;options&amp;nbsp;-ea[:...|:]&amp;nbsp;-enableassertions[:...|:]&amp;nbsp;enable&amp;nbsp;assertions&amp;nbsp;-da[:...|:]&amp;nbsp;-disableassertions[:...|:]&amp;nbsp;disable&amp;nbsp;assertions&amp;nbsp;-esa&amp;nbsp;|&amp;nbsp;-enablesystemassertions&amp;nbsp;enable&amp;nbsp;system&amp;nbsp;assertions&amp;nbsp;-dsa&amp;nbsp;|&amp;nbsp;-disablesystemassertions&amp;nbsp;disable&amp;nbsp;system&amp;nbsp;assertions&amp;nbsp;-agentlib:[=]&amp;nbsp;load&amp;nbsp;native&amp;nbsp;agent&amp;nbsp;library,&amp;nbsp;e.g.&amp;nbsp;-agentlib:hprof&amp;nbsp;see&amp;nbsp;also,&amp;nbsp;-agentlib:jdwp=help&amp;nbsp;and&amp;nbsp;-agentlib:hprof=help&amp;nbsp;-agentpath:[=]&amp;nbsp;load&amp;nbsp;native&amp;nbsp;agent&amp;nbsp;library&amp;nbsp;by&amp;nbsp;full&amp;nbsp;pathname&amp;nbsp;-javaagent:[=]&amp;nbsp;load&amp;nbsp;Java&amp;nbsp;programming&amp;nbsp;language&amp;nbsp;agent,&amp;nbsp;see&amp;nbsp;java.lang.instrument&amp;nbsp;-splash:show&amp;nbsp;splash&amp;nbsp;screen&amp;nbsp;with&amp;nbsp;specified&amp;nbsp;image#&amp;nbsp;测试Javac命令~&amp;nbsp;C:UsersAdministrator&amp;gt;javac用法：javac&amp;nbsp;&amp;lt;选项&amp;gt;&amp;nbsp;&amp;lt;源文件&amp;gt;其中，可能的选项包括：&amp;nbsp;-g&amp;nbsp;生成所有调试信息&amp;nbsp;-g:none&amp;nbsp;不生成任何调试信息&amp;nbsp;-g:{lines,vars,source}&amp;nbsp;只生成某些调试信息&amp;nbsp;-nowarn&amp;nbsp;不生成任何警告&amp;nbsp;-verbose&amp;nbsp;输出有关编译器正在执行的操作的消息&amp;nbsp;-deprecation&amp;nbsp;输出使用已过时的&amp;nbsp;API&amp;nbsp;的源位置&amp;nbsp;-classpath&amp;nbsp;&amp;lt;路径&amp;gt;&amp;nbsp;指定查找用户类文件和注释处理程序的位置&amp;nbsp;-cp&amp;nbsp;&amp;lt;路径&amp;gt;&amp;nbsp;指定查找用户类文件和注释处理程序的位置&amp;nbsp;-sourcepath&amp;nbsp;&amp;lt;路径&amp;gt;&amp;nbsp;指定查找输入源文件的位置&amp;nbsp;-bootclasspath&amp;nbsp;&amp;lt;路径&amp;gt;&amp;nbsp;覆盖引导类文件的位置&amp;nbsp;-extdirs&amp;nbsp;&amp;lt;目录&amp;gt;&amp;nbsp;覆盖安装的扩展目录的位置&amp;nbsp;-endorseddirs&amp;nbsp;&amp;lt;目录&amp;gt;&amp;nbsp;覆盖签名的标准路径的位置&amp;nbsp;-proc:{none,only}&amp;nbsp;控制是否执行注释处理和/或编译。&amp;nbsp;-processor[,,...]要运行的注释处理程序的名称；绕过默认的搜索进程&amp;nbsp;-processorpath&amp;nbsp;&amp;lt;路径&amp;gt;&amp;nbsp;指定查找注释处理程序的位置&amp;nbsp;-d&amp;nbsp;&amp;lt;目录&amp;gt;&amp;nbsp;指定存放生成的类文件的位置&amp;nbsp;-s&amp;nbsp;&amp;lt;目录&amp;gt;&amp;nbsp;指定存放生成的源文件的位置&amp;nbsp;-implicit:{none,class}&amp;nbsp;指定是否为隐式引用文件生成类文件&amp;nbsp;-encoding&amp;nbsp;&amp;lt;编码&amp;gt;&amp;nbsp;指定源文件使用的字符编码&amp;nbsp;-source&amp;nbsp;&amp;lt;版本&amp;gt;&amp;nbsp;提供与指定版本的源兼容性&amp;nbsp;-target&amp;nbsp;&amp;lt;版本&amp;gt;&amp;nbsp;生成特定&amp;nbsp;VM&amp;nbsp;版本的类文件&amp;nbsp;-version&amp;nbsp;版本信息&amp;nbsp;-help&amp;nbsp;输出标准选项的提要&amp;nbsp;-Akey[=value]&amp;nbsp;传递给注释处理程序的选项&amp;nbsp;-X&amp;nbsp;输出非标准选项的提要&amp;nbsp;-J&amp;lt;标志&amp;gt;&amp;nbsp;直接将&amp;nbsp;&amp;lt;标志&amp;gt;&amp;nbsp;传递给运行时系统&lt;/pre>&lt;p>&lt;span>这样我们就在Windows的系统中，配置好了Java环境。&lt;/span>&lt;/p>&lt;p>&lt;span>2 Java在Linux Ubuntu中安装&lt;/span>&lt;/p>&lt;p>&lt;span>Java安装，指定的是SUN Oracle官方的JDK软件包，而不是Linux Ubuntu系统中通过apt-get安装的OpenJDK。&lt;/span>&lt;/p>&lt;p>&lt;span>注：请一定注意版本，必须使用SUN Oracle官方的JDK软件包&lt;/span>&lt;/p>&lt;p>&lt;span>在Linux Ubuntu中，下载并安装JDK，这里我选择安装Java SE 1.6.45的64位版本的JDK。&lt;/span>&lt;/p>&lt;p>&lt;span>2.1 下载JDK&lt;/span>&lt;/p>&lt;p>&lt;span>不知道Oracle官方网站时候调整的JDK下载需要先登陆，因此直接使用wget命令，无法完成JDK的下载。&lt;/span>&lt;/p>&lt;p>&lt;span>我们有下面2种解决方法：&lt;/span>&lt;/p>&lt;ul class=" list-paddingleft-2">&lt;li>&lt;p>&lt;span>1). 从浏览器中登陆下载，然后再传到Linux的服务器&lt;/span>&lt;/p></description></item><item><title>35年编程史沉淀下来的8条宝贵经验</title><link>https://pangyd.com/post/149-358/</link><pubDate>Sun, 29 Oct 2017 19:39:10 +0800</pubDate><guid>https://pangyd.com/post/149-358/</guid><description>&lt;p>1&amp;nbsp;&lt;span>时刻提醒自己：学习&lt;/span>&lt;/p>&lt;p>学习某件事的第一步是承认你不知道。这听起来很正常，但经验丰富的程序员还记得要真正让自己承认这一点需要花多长时间。很多计算机科学专业的学生毕业的时候，都有一种很傲慢的态度，就是“我知道最好的”，但其实这只是一种虚张声势，他们不知道从哪里来的自信，就好像他们什么都知道，并且需要向每一位新同事强烈的证明这一点。换句话说:你所谓的“我知道我在做什么！”这种态度会妨碍你学习新的东西。&lt;/p>&lt;p>2. 不要试图证明自己是正确的&lt;/p>&lt;p>要想成为优秀的人，你必须学会吃一堑长一智。但是千万小心，经验也可能教会我们重复一些不良行为，甚至也教会我们养成一些不好的习惯。我们都遇到过有8年经验的程序员。对于他们来说，同样的经历，重复了8次。为了避免这种综合症，看看你做的每一种事情，然后问自己:“我怎样才能让它变得更好?”&lt;/p>&lt;p>新手(以及很多经验丰富的开发人员)会看着他们自己写的代码，欣赏它的奇妙。他们编写测试来证明他们写的代码是可以运行的，而不是试图让它运行失败。真正优秀的程序员会积极地寻找他们的错误在哪里，因为他们知道最终用户会发现这些遗漏的bug。&lt;/p>&lt;p>&lt;span style="text-align: center">3. “代码可以运行了”这个目标不是终点，而是起点&lt;/span>&lt;/p>&lt;p>是的，你的第一步总是想写出质量很高的代码，而且代码上面都写满了注释。但是一般的程序员在这一点上就退出，然后继续下一件事。&lt;/p>&lt;p>但是一旦“完成”就停止了这种思想就像是拍一张快照，然后期待它是一件艺术品一样。伟大的程序员都知道第一次迭代只是一次迭代。它运行起来了,恭喜你!但你的工作还有很多。现在,使它变的更好。&lt;/p>&lt;p>其实这个过程就是在定义“更好”的含义。让它变得更快能有什么价值吗?可重用更高有什么好处吗?更可靠吗?答案随着每个应用程序的不同而不同，但是过程都是一样的。&lt;/p>&lt;p>4. 写三次代码&lt;/p>&lt;p>好的程序员目标是写出可以运行的软件就可以了。伟大的程序员写出来的软件目标是运行得非常好。通过一次编写这种情况几乎不可能发生。最好的软件通常被写三次:&lt;/p>&lt;p>首先，编写软件以向你自己(或客户)证明解决方案是可行的。其他人可能没有意识到这只是一个概念验证，但你确实这么做了。&lt;/p>&lt;p>第二次可以让它正常地运行。&lt;/p>&lt;p>第三次你能够让它平稳的运行。&lt;/p>&lt;p>当你看到最优秀的开发人员的工作时，这种级别的工作可能并不明显。他们所做的一切看起来都很出色，但你没有看到的是，即使是开发界的大腕儿，也可能在向其他人展示他们的软件之前就已经抛弃了第一个和第二个版本。抛弃之前的代码并开始编写另一个版本是一种强大的方式，可以将“更好地”融入到您的个人工作流程中。&lt;/p>&lt;p>如果没有其他情况，通过“写三次代码”可以告诉你解决问题的方法有多少种。而且它可以防止你陷入停滞不前的状态。&lt;/p>&lt;p>5. 阅读大量的代码&lt;/p>&lt;p>你可能希望我能够引导这个建议，实际上，这也是提高编程技能的最常见和最有价值的建议。阅读他人代码的原因也很重要，只是不是很明显而已。&lt;/p>&lt;p>当阅读其他人的代码时，你会看到其他人是如何解决编程问题的。但不要把它当成是文学作品，而是把它当成一种教训和一种挑战。想要变得更好，问问自己：&lt;/p>&lt;p>那块代码我该怎么写呢?既然你已经看到了别人的解决方案，那你会有什么思路呢?&lt;/p>&lt;p>我学到了什么？我如何将这种技术应用到我过去编写的代码中？（“我从来没有想过可以使用递归下降处理那块的逻辑”）。&lt;/p>&lt;p>我如何改进这段代码?如果这是一个开源项目，你对自己的解决方案更有信心，那就去做吧！&lt;/p>&lt;p>以作者的风格编写代码。练习这个可以帮助你进入作者的思维，这可以提高你的同情心。&lt;/p>&lt;p>不要只是漫不经心地思考这些步骤。写下你自己的答案，无论是在个人日志、博客、审查代码的过程中，还是与其他开发人员交流的论坛中。就像向朋友解释问题可以帮助你解决问题一样，记录和分享你的分析可以帮助你理解为什么你会以一种特定的方式对别人的代码做出反应。这是我之前提到的自省的一部分，帮助你冷静地判断你自己的优点和缺点。&lt;/p>&lt;p>警告:在不需要成为一名优秀程序员的情况下，很容易阅读大量的代码，就像一个想要成为作家的人可以在不提高自己散文的情况下阅读伟大的文学作品一样。很多开发人员都在寻找开源或其他软件来“找到答案”，而且很可能是复制和粘贴代码来解决类似的问题。这样做实际上会让你成为一个更糟糕的程序员，因为你盲目地接受别人的智慧而不去审视它。(另外，它可能比夏季野餐还要麻烦，但因为你没有花时间去理解它，你永远不会意识到你就像是大自然的搬运工一样，只是在做体力劳动。)&lt;/p>&lt;p>&lt;span style="text-align: center">6. 不要把编写代码仅仅看作是任务&lt;/span>&lt;/p>&lt;p>从事个人编程项目有很多优势。首先，它为你提供了一种学习工具以及学习技术的方法，而这些工具和技术在你当前的工作中是用不到的，但是这将使你在下一份工作中更有市场。无论你是为开源项目做贡献，还是为当地社区组织做公益工作，你都能获得技术技能和自信。(此外，你的个人项目向潜在雇主证明，你是一个从不停止学习的人。)&lt;/p>&lt;p>编写代码的另一个好处是它强迫你自己去解决问题。你不能把这些难啃的问题留给别人，所以它会让你过早地寻求帮助。&lt;/p>&lt;p>专业提示:不要只选择那些你永远不会失败的个人项目。你需要失败!但是你可能不想在工作中失败，或者给你限定期限时你也不想失败。&lt;/p>&lt;p>7.尽一切可能做到与其他开发人员面对面的工作&lt;/p>&lt;p>倾听别人的意见是很有帮助的。这可能意味着结对编程，或者参加黑客马拉松，或者加入一个编程用户组(比如Vermont Coders Connection)。当你为一个开源项目做贡献时，要关注一下你从用户和其他开发者得到的反馈意见。你在他们的批评中看到了什么共同点?&lt;/p>&lt;p>这样做你可能会很幸运地认识了一位可以完全信任的导师，无路是编码技术还是职业决策，你都可以完全信任他。所以不要浪费这些机会。&lt;/p>&lt;p>8. 你是在学习技术,而不是在学如何使用工具&lt;/p>&lt;p>编程语言、工具和方法这些都只是一时的。这就是为什么需要你在这么多的语言和框架中尽可能多的获得经验。重点关注编程基础，因为基础永远不会改变;更关注体系结构而不是如何编程。如果你觉得做某件事只有一种正确的方式，那可能是时候进行现实核查了。条条框框的限制会妨碍你学习新事物的能力，也会使你很难适应变化。&lt;/p>&lt;p>我可以继续前进，但自我提升的关键原则是知道何时停止。&lt;/p>&lt;p style="text-align: center">&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" max-width="600">&lt;/p>&lt;div>&lt;br>&lt;/div></description></item><item><title>GitHub 上最火的 Java 框架</title><link>https://pangyd.com/post/148-github-java/</link><pubDate>Sat, 28 Oct 2017 20:30:26 +0800</pubDate><guid>https://pangyd.com/post/148-github-java/</guid><description>&lt;p>&lt;span>Java 是目前最需要的编程语言之一。在这里，我们已经挖掘了一些关于框架趋势的有用信息，也就是最受开发者青睐的 Java 框架，名单如下&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;/p>&lt;p>&lt;p>&lt;/p>&lt;/p>&lt;section data-role="outer" label="Powered by 135editor.com" style="text-align: start">&lt;section class="" data-tools="135编辑器" data-id="87856">&lt;section>&lt;section class="">1&lt;/section>&lt;section class="" data-bgless="lighten" data-brushtype="text" data-bglessp="20%">Spring MVC&lt;/section>&lt;/section>&lt;/section>&lt;p>&lt;span>&lt;a href="https://github.com/spring-projects/spring-framework/tree/master/spring-webmvc" target="_blank" class="link link-normal">网页链接&lt;/a>&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>自从 10 多年前的第一次发布之后，SpringMVC 老当益壮，继续保持着领头羊的地位。在其完全拥抱 MVC 框架之后，Spring 不断的发展与变化着，转变成了一个功能全面的面向互联网应用程序的 Java 框架, 它能提供给软件工程师的是一个用于 Web 应用程序开发的强大工具集，以及针对安全项目的应用程序配置。具有如下特性：&lt;/span>&lt;/p>&lt;p>&lt;span>● 简单的 POJO 测试数据注入方式。&lt;/span>&lt;/p>&lt;p>&lt;span>● 增强过的模块化，因此拥有更好的代码可靠性。&lt;/span>&lt;/p>&lt;p>&lt;span>● 不同模块之间解耦和。&lt;/span>&lt;/p>&lt;p>&lt;span>● 能灵活运用的依赖注入（DI）。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;section class="" data-tools="135编辑器" data-id="87856">&lt;section>&lt;section class="">2&lt;/section>&lt;section class="" data-bgless="lighten" data-brushtype="text" data-bglessp="20%">Spring Boot&lt;/section>&lt;/section>&lt;/section>&lt;p>&lt;span>&lt;a href="https://github.com/spring-projects/spring-boot" target="_blank" class="link link-normal">网页链接&lt;/a>&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>Spring Boot 项目旨在简化创建产品级的 Spring 应用和服务。你可通过它来选择不同的 Spring 平台。可创建独立的 Java 应用和 Web 应用，同时提供了命令行工具来允许 'spring scripts'。Spring Boot 不生成代码，完全无需 XML 配置。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p></description></item><item><title>历数Java程序员面试失败的5大原因</title><link>https://pangyd.com/post/147-java5/</link><pubDate>Fri, 27 Oct 2017 19:31:56 +0800</pubDate><guid>https://pangyd.com/post/147-java5/</guid><description>&lt;p style="text-align: center">&lt;img data-src="https://pangyd.com/uploads/2017/10/74c10f869f038762.jpg" class="" data-ratio="0.6118721461187214" data-w="438" data-type="jpeg" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-fail="0">&lt;/p>&lt;h2>&lt;span>&lt;span>&lt;span>＃1 说得太少&lt;/span>&lt;/span>&lt;/span>&lt;/h2>&lt;p>&lt;span>尤其是那些开放式的问题，如“请介绍下你自己”或“请讲一下你曾经解决过的复杂问题”。面试官会通过你对这些技术和非技术问题的回答来评估你的激情。他们也会通过模拟团队氛围和与你的交流互动来判断你的经验和能力。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>所以，仅仅只用两三句话来回答不但不能显示出你对这个专业的兴趣，还会让整个面试过程显得非常无聊。如果你不能很好地说明你的经验、成就和技能可以给企业带来的价值，那么你的竞争力毫无疑问就高不起来。所以，你需要对一些最常见的开放式问答作充分的准备，学会推销自己。&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;br>&lt;img class="" data-ratio="1.443298969072165" data-s="300,640" data-src="https://pangyd.com/uploads/2017/10/74c10f869f038762.jpg" data-type="jpeg" data-w="194" width="auto" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-fail="0">&lt;br>&lt;/p>&lt;h2>&lt;span>&lt;span>＃2 说得太多&lt;/span>&lt;/span>&lt;/h2>&lt;p>&lt;span>不断地说，不断地说，却并没有什么实质性的内容。换句话说，就是废话连篇，言之无物。如果你不能简洁的解释问题，那么面试官就会怀疑你在工作时的表现是不是也会像你的谈话一样拖泥带水？可以先问问面试官，确定是否真的需要详细解释。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>解释也是一门艺术，关键是确定重点，如果需要的话再深入到细节。当聊到业务的时候，就应该从业务的角度看问题，不要涉及任何技术术语。学会用简洁明了的方式解释问题。如果你能时刻把握主旨，那么这一点也不是问题。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;img data-src="https://pangyd.com/uploads/2017/10/74c10f869f038762.jpg" class="" data-ratio="0.583864118895966" data-w="471" data-type="jpeg" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-fail="0">&lt;/span>&lt;/p>&lt;h2>&lt;span>&lt;span>＃3回答不出一些必知的基本技术问题&lt;/span>&lt;/span>&lt;/h2>&lt;p>&lt;span>面试不是技术竞赛，不是看谁答对的问题多，但是有一些“必须知道”的核心Java和Web基础知识，你不能不知。例如，对于Java开发人员&lt;/span>&lt;/p>&lt;p>&lt;span>1）不知道“==”和equals之间的区别。&lt;/span>&lt;/p>&lt;p>&lt;span>2）不知道equals和hashCode方法被隐式调用时的约定。&lt;/span>&lt;/p>&lt;p>&lt;span>3）不知道OO的概念和设计原则。&lt;/span>&lt;/p>&lt;p>&lt;span>4）不能很好地处理多线程。&lt;/span>&lt;/p>&lt;p>&lt;span>5）不知道如何在HTTP客户端与服务器端之间保持状态。&lt;/span>&lt;/p>&lt;p>&lt;span>6）不能解释曾投入精力过的应用程序的高层体系结构。&lt;/span>&lt;/p>&lt;p>&lt;span>7）不知道SQL。&lt;/span>&lt;/p>&lt;p>&lt;span>…&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;img data-src="https://pangyd.com/uploads/2017/10/74c10f869f038762.jpg" class="" data-ratio="0.968" data-w="125" data-type="jpeg" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-fail="0">&lt;/span>&lt;/p>&lt;h2>&lt;span>&lt;span>＃4既写不好简单的代码，又回答不出如何解决棘手的问题&lt;/span>&lt;/span>&lt;/h2>&lt;p>&lt;span>作为一个开发人员，你应该根据自己的经验水平，来针对给定的问题和情况编写代码。特别是如果碰到一个比较棘手的问题，那么即使你还没有解决方案，也应该将你的思路讲给面试官听。当然这在面试时会让人特别紧张，尤其是在还有时间限制的情况下，但是你也必须保持冷静，至少应该说明你将如何试着去解决问题的方法。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;h2>&lt;span>&lt;span>＃5糟糕的礼仪和态度&lt;/span>&lt;/span>&lt;/h2>&lt;p>&lt;span>迟到，不适宜的着装，抖手抖脚，没有眼神接触，过于紧张，没有提问，显示不出对这份职业的兴趣，“我什么都知道”的高傲态度，贬低你的现在和以前的雇主，遇到技术问题时烦躁不安或者垂头丧气，为自己找理由而不是虚心接受错误，与面试官发生争执，不好的肢体语言，随波逐流而没有自己的看法，过于呆板，撒谎，嗓门太大，无法成为良好的倾听者，等等。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;img data-src="https://pangyd.com/uploads/2017/10/74c10f869f038762.jpg" class="" data-ratio="0.5866336633663366" data-w="404" data-type="jpeg" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-fail="0">&lt;/span>&lt;/p></description></item><item><title>Java数据结构与算法</title><link>https://pangyd.com/post/146-java/</link><pubDate>Thu, 26 Oct 2017 22:56:35 +0800</pubDate><guid>https://pangyd.com/post/146-java/</guid><description>&lt;p>&lt;span>刚学习数据结构与算法时，就被告知&lt;span>&amp;nbsp;“程序=算法+数据结构”&lt;/span>，而这段话来自于对点计算机科学家Niklaus Wirth在1976年出版的一本书的书名，后来这句话也成为计算机工作者之间流传的一句名言，小编也用惨痛的经历告诉大家这也是一个很重要的知识点。&lt;/span>&lt;/p>&lt;p>&lt;span>&amp;nbsp;&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;img data-s="300,640" data-type="jpeg" data-src="https://pangyd.com/uploads/2017/10/74c10f869f038762.jpg" data-copyright="0" class="" data-ratio="1.0909090909090908" data-w="110" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-fail="0">&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;br>&lt;/p>&lt;p>&lt;span>&lt;span>那么到底什么是数据结构和算法，数据结构算法又有什么用呢？&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>首先来说说什么是数据结构，直接上图&lt;/span>&lt;/p>&lt;p>&lt;span>&amp;nbsp;&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;img data-s="300,640" data-type="jpeg" data-src="https://pangyd.com/uploads/2017/10/74c10f869f038762.jpg" data-copyright="0" class="" data-ratio="0.59613196814562" data-w="879" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-fail="0">&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;br>&lt;/p>&lt;p>&lt;span>从图中我们可以很直观的看出数据结构涵盖的内容。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>算法的介绍就相对抽象了，百度百科给出的解释是&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>算法是对特定问题求解步骤的一种描述，它是指令的有限序列，其中每一条指令表示一个或者多个操作。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>但是我们从他的特性来理解就会简单多了。&lt;span>算法主要有五个特性&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>· 有穷性：指令序列是有限的&lt;/span>&lt;/p>&lt;p>&lt;span>· 确定性：每条语句的含义明确，无二义性&lt;/span>&lt;/p>&lt;p>&lt;span>· 可行性：每条语句都应在有限的时间内完成&lt;/span>&lt;/p>&lt;p>&lt;span>· 输入：零个或者多个输入&lt;/span>&lt;/p>&lt;p>&lt;span>· 输出：一个或者多个输出&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;img data-s="300,640" data-type="jpeg" data-src="https://pangyd.com/uploads/2017/10/74c10f869f038762.jpg" data-copyright="0" class="" data-ratio="0.8" data-w="1280" width="328px" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-fail="0">&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;br>&lt;/p>&lt;p>&lt;span>说到数据结构算法的用处，当你用着java容器类很爽的时候，你有没有想过，怎么ArrayList像一个无限扩充的数组，也好像一个链表。好用吗？当然好用这就是数据结构的用处，只不过你在不知不觉中使用了。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>用于现实世界的存储，我们使用的工具和建模。每种数据结构有自己的优点和缺点，想想如果Google的数据用的是数组的存储，我们还能方便地查询到所需要的数据吗。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p></description></item><item><title>Java打飞机小游戏（附完整源码)</title><link>https://pangyd.com/post/144-java/</link><pubDate>Tue, 24 Oct 2017 22:56:12 +0800</pubDate><guid>https://pangyd.com/post/144-java/</guid><description>&lt;p>&lt;br>&lt;/p>&lt;p style="text-align: justify">&lt;span id="article-img-0" class="a-image">&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/span>&lt;/p>&lt;p style="text-align: justify">写在前面&lt;/p>&lt;p style="text-align: justify">技术源于分享，所以今天抽空把自己之前用java做过的&lt;a href="https://www.yidianzixun.com/channel/w/%E5%B0%8F%E6%B8%B8%E6%88%8F" target="_blank">小游戏&lt;/a>整理贴出来给大家参考学习。java确实不适合写桌面应用，这里只是通过这个游戏让大家理解&lt;a href="https://www.yidianzixun.com/channel/w/oop" target="_blank">oop&lt;/a>面向对象编程的过程，纯属娱乐。代码写的很简单，也很容易理解，并且注释写的很清楚了，还有问题，自己私下去补课学习。&lt;/p>&lt;p style="text-align: justify">完整代码&lt;/p>&lt;h2 style="text-align: justify">敌飞机&lt;/h2>&lt;p style="text-align: justify">&lt;span id="article-img-1" class="a-image">&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/span>&lt;/p>&lt;h2 style="text-align: justify">分数奖励&lt;/h2>&lt;p style="text-align: justify">&lt;span id="article-img-2" class="a-image">&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/span>&lt;/p>&lt;h2 style="text-align: justify">蜜蜂&lt;/h2>&lt;p style="text-align: justify">&lt;span id="article-img-3" class="a-image">&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/span>&lt;/p>&lt;h2 style="text-align: justify">子弹类：是飞行物体&lt;/h2>&lt;p style="text-align: justify">&lt;span id="article-img-4" class="a-image">&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/span>&lt;/p>&lt;h2 style="text-align: justify">敌人的分数&lt;/h2>&lt;p style="text-align: justify">&lt;span id="article-img-5" class="a-image">&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/span>&lt;/p>&lt;h2 style="text-align: justify">飞行物(敌机，蜜蜂，子弹，英雄机)&lt;/h2>&lt;p style="text-align: justify">&lt;span id="article-img-6" class="a-image">&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/span>&lt;span id="article-img-7" class="a-image">&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/span>&lt;/p>&lt;h2 style="text-align: justify">英雄机&lt;/h2>&lt;p style="text-align: justify">&lt;span id="article-img-8" class="a-image">&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/span>&lt;span id="article-img-9" class="a-image">&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/span>&lt;span id="article-img-10" class="a-image">&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/span>&lt;/p>&lt;h2 style="text-align: justify">游戏启动主类&lt;/h2>&lt;p style="text-align: justify">&lt;span id="article-img-11" class="a-image">&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/span>&lt;span id="article-img-12" class="a-image">&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/span>&lt;span id="article-img-13" class="a-image">&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/span>&lt;span id="article-img-14" class="a-image">&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/span>&lt;span id="article-img-15" class="a-image">&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/span>&lt;span id="article-img-16" class="a-image">&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/span>&lt;span id="article-img-17" class="a-image">&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/span>&lt;span id="article-img-18" class="a-image">&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/span>&lt;span id="article-img-19" class="a-image">&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/span>写在最后&lt;/p></description></item><item><title>深入解析Java垃圾回收机制</title><link>https://pangyd.com/post/143-java/</link><pubDate>Mon, 23 Oct 2017 21:41:45 +0800</pubDate><guid>https://pangyd.com/post/143-java/</guid><description>&lt;p>引入垃圾回收 哪些内存需要回收？ 引用计数法 可达性分析 如何回收 Marking 标记 Normal Deletion 清除 Deletion with Compacting 压缩 为什么需要分代收集？ JVM的分代 新生代 老年代 永久代 分代垃圾收集过程详述 引入垃圾回收&lt;/p>&lt;p>JAVA&lt;/p>&lt;p>程序计数器、 虚拟机栈、 本地方法栈3个区域随线程而生，随线程而灭；栈中的栈帧随着方法的进入和退出而有条不紊地执行着出栈和入栈操作。 每一个栈帧中分配多少内存基本上是在类结构确定下来时就已知的（尽管在运行期会由JIT编译器 进行一些优化，但在本章基于概念模型的讨论中，大体上可以认为是编译期可知的），因此这几个区域的内存分配和回收都具备确定性，在这几个区域内就不需要过多考虑回收的问题，因为方法结束或者线程结束时，内存自然就跟随着回收了。 而Java堆和方法区则不一样，一个接口中的多个实现类需要的内存可能不一样，一个方法中的多个分支需要的内存也可能不一样，我们只有在程序处于运行期间时才能知道会创建哪些对象，这部分内存的分配和回收都是动态的，垃圾收集器所关注的是这部分内存—–《深入理解Java虚拟机》 自动垃圾回收机制就是寻找Java堆中的对象，并对对象进行分类判别，寻找出正在使用的对象和已经不会使用的对象，然后把那些不会使用的对象从堆上清除。 自动垃圾回收机制就是要解决三个问题：&lt;/p>&lt;p>哪些内存需要回收？ 什么时候回收？ 如何回收？ 哪些内存需要回收？&lt;/p>&lt;p>引用计数法&lt;/p>&lt;p>对于第一个问题，也就是判断是否还需要使用，最简单的方法就是通过目前是否有引用指向这个对象，如果没有就说明这个对象不会再被使用了，如果有就说明这个对象可能还会继续被使用，这种通过引用是否存在的方法就叫做引用计数法，但这个方法存在一个问题就是无法解决对象循环引用的问题，因此又出现了可达性分析的方法来判断对象是否可以被会回收。&lt;/p>&lt;p>可达性分析&lt;/p>&lt;p>这个算法的基本思路就是通过一系列的称为“GC Roots”的对象作为起始点，从这些节点开始向下搜索，搜索所走过的路径称为引用链（Reference Chain），当一个对象到GC Roots没有任何引用链相连（用图论的话来说，就是从GC Roots到这个对象不可达）时，则证明此对象是不可用的。 在Java语言中，可作为GC Roots的对象包括下面几种：&lt;/p>&lt;p>虚拟机栈（栈帧中的本地变量表）中引用的对象。 方法区中类静态属性引用的对象。 方法区中常量引用的对象。 本地方法栈中JNI（即一般说的Native方法）引用的对象。 如何回收&lt;/p>&lt;p>垃圾收集器通常会帮我们在后台自动进行垃圾回收。关于具体的回收过程只要有以下这些步骤&lt;/p>&lt;p>Step 1: Marking 标记 第一步就是标记，也就是垃圾收集器会找出那些需要回收的对象所在的内存和不需要回收的对象所在的内存，并把它们标记出来，简单的说，也就是先找出垃圾在哪 所有堆中的对象都会被扫描一遍，以此来确定回收的对象，所以这通常会是一个相对比较耗时的过程&lt;/p>&lt;p>Step 2: Normal Deletion 垃圾收集器会清除掉上一步标记出来的那些需要回收的对象区域&lt;/p></description></item><item><title>分享优秀Java程序员应有的编程风格</title><link>https://pangyd.com/post/142-java/</link><pubDate>Sun, 22 Oct 2017 21:36:06 +0800</pubDate><guid>https://pangyd.com/post/142-java/</guid><description>&lt;p>今天突发奇想，对编码习惯和编程风格很感兴趣，于是乎，找了一下关于编程风格（Java篇）的资料，希望对爱好编码或者开始学习编码的同学有帮助！&lt;/p>&lt;p>来自《The Elements of Java Style》-《Java编程风格》一书，值得一读的书籍，会让你在细节上节省很多时间，合作之间更加愉快！&lt;/p>&lt;p>好处不多说了，但是有几个原则如下：&lt;/p>&lt;p>1.保持原有风格&lt;/p>&lt;p>2.坚持最小惊奇原则&lt;/p>&lt;p>3.第一次就做对&lt;/p>&lt;p>4.记录所有非规范行为&lt;/p>&lt;p>格式规范：&lt;/p>&lt;p>1.缩进嵌套的代码：在每个代码块和嵌套中加入缩进，缩进代码，加强可读性。这些地方包括【类定义，内部类定义，方法定义，静态块，for循环语句，if-else语句，try、catch和finally块，匿名内部类，while语句，do-while语句】&lt;/p>&lt;p>2.断开很长的句子：第一，如果包含了逗号，那么在每一个逗号后面都另起一行，把逗号后面的每一个表达式都和逗号前面的表达式的第一个字母对齐。第二，应该在优先级最低的运算符之前断行。&lt;/p>&lt;p>3.使用空白：关键字和左括号之间，右括号和紧随其后的关键字，除了”.”之外的运算符与其前后的表达式之间用空格隔开。每个逻辑上独立的方法和代码段之间，定义类或者接口的成员之间，每个类和接口之间应该加入空白行。&lt;/p>&lt;p>4.不要直接使用Tab控制符：不同环境对Tab控制符的解释也是不同的。&lt;/p>&lt;p>命名约定：&lt;/p>&lt;p>1.名称应该具有实际意义&lt;/p>&lt;p>2.使用人们熟悉的名称&lt;/p>&lt;p>3.谨慎使用过长的名字，可以使用简明通用的缩写&lt;/p>&lt;p>4.尽量保留元音字母&lt;/p>&lt;p>5.缩写词的第一个字母大写&lt;/p>&lt;p>6.不要使用大小写来区分的名字&lt;/p>&lt;p>包命名：&lt;/p>&lt;p>1.用你所在组织的域名的倒序小写形式作为包的根限定词&lt;/p>&lt;p>2.使用单独的小写词作为每个包的根名&lt;/p>&lt;p>3.仅当新旧版本二进制兼容的时候，其包可以使用相同的名字，否则，请使用新名字&lt;/p>&lt;p>类型命名：&lt;/p>&lt;p>1.类和接口名中的每个单词的第一个字母大写&lt;/p>&lt;p>类命名：&lt;/p>&lt;p>1.用名词命名类&lt;/p>&lt;p>2.具有成组相关属性，静态服务或者常量的类名字使用复数形式&lt;/p>&lt;p>接口命名：&lt;/p>&lt;p>1.用名词或者形容词命名接口&lt;/p>&lt;p>方法命名：&lt;/p>&lt;p>1.方法名中的第一个单词小写，其后每个单词的第一个字母大写&lt;/p>&lt;p>2.用动词命名方法&lt;/p>&lt;p>3.遵循JavaBean中命名属性访问函数方法：set，get，is&lt;/p>&lt;p>变量命名：&lt;/p>&lt;p>1.变量命中的第一个单词小写，其后的每个单词的第一个字母大写&lt;/p>&lt;p>2.用名词命名变量&lt;/p>&lt;p>3.集合引用名要用复数形式&lt;/p>&lt;p>4.为不重要的临时变量简历并使用一套标准名字&lt;/p>&lt;p>字段命名：&lt;/p>&lt;p>1.使用this字段变量可以区分开局部变量&lt;/p>&lt;p>参数命名：&lt;/p>&lt;p>1.构造函数或者”set”方法给字段分配参数赋值，参数名应该和字段名相同&lt;/p>&lt;p>常量命名：&lt;/p>&lt;p>1.常量的每个单词均大写，单词之间使用下划线连接&lt;/p>&lt;p>文档约定：&lt;/p>&lt;p>1.为使用和维护你的代码的人编写文档&lt;/p>&lt;p>2.注释和代码要同步&lt;/p>&lt;p>3.使用积极的语气，省略无用的词语&lt;/p>&lt;p>注释类型：&lt;/p>&lt;p>1.用文档注释来描述编程接口&lt;/p>&lt;p>2.用标准注释格式隐藏代码而不必删除它们&lt;/p>&lt;p>3.用单行注释解释实现细节&lt;/p>&lt;p>文档注释：&lt;/p>&lt;p>1.在编写代码前描述编程接口&lt;/p>&lt;p>2.为公用，受保护，包，私有成员建立文档&lt;/p>&lt;p>3.为每个包编写总结和概述&lt;/p>&lt;p>4.为包的每个应用程序或组编写概述&lt;/p>&lt;p>注释风格：&lt;/p>&lt;p>1.对所有文档注释使用统一的格式和组织结构&lt;/p>&lt;p>2.关键字，标识符和常量应放到…标签中&lt;/p>&lt;p>3.将代码放入&lt;/p>&lt;p>…标签中&lt;/p>&lt;p>4.在标识符第一次出现的时候用{@link}标签&lt;/p>&lt;p>5.为Javadoc标签简历并使用一套固定的顺序&lt;/p>&lt;p>6.使用第三人称叙述的形式&lt;/p></description></item><item><title>有一个程序员男朋友是怎样的体验？</title><link>https://pangyd.com/post/141/</link><pubDate>Sat, 21 Oct 2017 20:53:09 +0800</pubDate><guid>https://pangyd.com/post/141/</guid><description>&lt;p>高中毕业我们两个人在一起，现在他在上班，我在读研。大学时期他学的是计算机科学技术，毕业后顺利成为了一名程序猿。现在网络上对程序员这个职业议论纷纷。&lt;/p>&lt;p>他现在的工作职位是中级前端工程师，我经常吐槽他名字听上去很高大上，但实际还不是一个程序员。&lt;/p>&lt;p>作为资深的程序员女友，来聊聊有一个程序员男友的体验。&lt;/p>&lt;p>生活日常&lt;/p>&lt;p>程序员不是只会修电脑的生物，他们在生活中有很多技能。男朋友是程序员后基本自己的电脑出问题都不用再担心，电脑清灰、重装系统，他可以承包一切电子产品的障碍维修工作。大学的时候我们寝室所有女生电脑出问题，我都第一时间先给男朋友打电话报修，虽然他一再强调自己不是修理工，但是每次都修的自得其乐。&lt;/p>&lt;p>感觉有一个技术大牛陪在身边，简直无所不能。&lt;/p>&lt;p>男朋友高中理科读上来，毕业后也算是标准的工科男。很多人觉得工科男智商高情商低。因为他们不善于交际，每天都只是和一些数字符号代码打交道。&lt;/p>&lt;p>这一点我深有感触。关于情商方面，他好像永远不懂“浪漫”两个字的含义。在一起这么多年从来没有送过花花草草给我！每逢过节日都需要我提前提醒他“嗯纪念日快到了！生日快到了！情人节快到了！”最近开始送我口红，都是我在网上选好款式和色号直接把链接甩给他。有时候抱怨一点都没有惊喜感，他反倒安慰这才是实在的过日子。&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>有时候聊天给他抱怨为什么不学着别的男生给自己女朋友制造惊喜，比如送送花啥的。然后他竟然去百度！！百度！！搜索男人为什么要送花给女人。我当时也是被他这个点萌到不行，突然间又觉得他很可爱。&lt;/p>&lt;p>再看下面 ️&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>连求婚这种事都要提前告诉我的吗！我真的是又爱又恨，能不能有点惊喜了。在我看来这种人生大事肯定男生要好好准备，然后制造一个浪漫的求婚计划，而不是直接告诉我，感觉不接受都不行了，有一种被胁迫扯证的感觉。&lt;/p>&lt;p>很多人说程序员的性格就是闷骚，看着内向不爱说话，实际心里可有货了。虽然我男朋友不太懂浪漫，但是在生活上还是给予了我足够的照顾，有时候细心到惊讶我的程度。&lt;/p>&lt;p>都说恋爱中的女人智商为零。&lt;/p>&lt;p>那我们两个人刚好互补呀，他智商高情商低，我情商高智商低。&lt;/p>&lt;p>在生活中他幽默、可爱，偶尔犯二，和他在一起永远不觉得无聊。&lt;/p>&lt;p>优点爆表&lt;/p>&lt;p>生活中我是一个急性子，而且性格多变。但刚好他超级有耐心。可能是因为工作性质原因，经常听到他说“客户改需求了，客户又改需求了噼里啪啦的，换作我早就不干了。每次看他对待客户都是一副客户虐我千百遍，我待客户如初恋的感觉。&lt;/p>&lt;p>对待善变的客户都如此有耐心，所以在他看来，我善变的性格也属于正常范围了。&lt;/p>&lt;p>责任心也是一大特点，对于自己编程过程中出现的bug，一副不改好不睡觉的态度，所以有时候在电脑面前一坐就是凌晨，下班回家只是换个地方加班。他说没有责任心的程序员写出来的代码都是问题。&lt;/p>&lt;p>他们善于学习，上进。只要有空就会专研技术方面的知识、整理笔记。虽然我男朋友在上班了，但是依然坚持每天看书学英语。有时候在他面前我感觉自己这个研究生特别惭愧，英语还没他好呢。他学习能力也是超强，总是能很快自学成功，果然智商高的生物惹不起。&lt;/p>&lt;p>迷恋电子产品，跟他在一起后我的电子产品更新换代的速度加快了，每次看他吐槽一个产品，过段时间就买回来了（真不知道是啥心态）。以前觉得自己买化妆品挺贵，但是了解他的键盘、电竞椅价格后，好像觉得我这点也不算啥了。&lt;/p>&lt;p>程序员这个职业，都不会太穷。（你们懂的）&lt;/p>&lt;p>他们不会有太多的社交去维系，每天下班就是宅。身边除了男生就是男生，这一点是其他职业比不了的。所以当程序员的女朋友可以放宽心，你不用花精力去窥探男朋友身边的人，毕竟十个程序员，七个单身狗，两个搞基友，只有一个有女朋友！&lt;/p>&lt;p>坚实后盾&lt;/p>&lt;p>对于程序员来说虽然加班是家常便饭，虽然有写不完的代码改不完的bug，但是每次只要我需要他，他就会放下手上的事第一时间出现。&lt;/p>&lt;p>所以不是说所有的程序员都木讷、不体贴，至少我身边这位不是。&lt;/p>&lt;p>他知道我不敢一个人在家呆太晚，所以每次都会尽快回家陪我，他知道我喜欢吃的东西，每次帮我买零食回家样样都是我的最爱，他比我还了解自己。&lt;/p>&lt;p>从不和我吵架，有时候我在气头上他自己就去写代码，过一会我自己气消了就像啥也没发生。&lt;/p>&lt;p>他虽然喜欢玩游戏、看直播，但是只要我不想，就会陪我一起追韩剧，看电影，任我在旁边怒吼好帅好帅啊他就冷冷地冒句：你身边这位才最帅。&lt;/p>&lt;p>生活上学习上有任何困难，第一时间找男朋友，好像没有他解决不了的事情，就像我人生导师一样。&lt;/p>&lt;p>程序员之间的冷幽默也是外人理解不了的，他们之间存在的鄙视链就相对简单了：&lt;/p>&lt;p>女朋友漂亮的程序员——女朋友不漂亮的程序员——有女朋友的程序员——单身程序员。&lt;/p>&lt;p>每次我吐槽他职业的时候他就安慰我说：找程序员做老公就对了，因为他们只会找bug，不会找小三。&lt;/p>&lt;p>有时候被他蠢萌的样子给融化，外人都觉得程序员很闷，其实并不都是这样。他们还是冷幽默、体贴、善解人意、聪明。我觉得现在外行对这个职业误会挺深的，并不是所有程序员都是戴个眼镜，穿着格子衬衫，背着书包，只会修电脑打游戏。&lt;/p>&lt;p>你想要的，都会尽力给你。面包和爱情，他们一样也不少。&lt;/p>&lt;p>我很谢谢我这位呆萌的程序员男朋友，这么多年爱我如初。事业上，生活里我们相互扶持包容，风雨兼程。&lt;/p>&lt;p>其实程序员男朋友也没啥特别的，但是对于我来说他就是独一无二的。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>本文链接:https://buluo.qq.com/p/detail.html?bid=11314&amp;amp;pid=8931774-1508579587&amp;amp;from=share_copylink&lt;/p></description></item><item><title>Java集合面试问题和答案</title><link>https://pangyd.com/post/140-java/</link><pubDate>Fri, 20 Oct 2017 20:19:28 +0800</pubDate><guid>https://pangyd.com/post/140-java/</guid><description>&lt;p style="text-align: justify">&lt;span>1.Java集合框架是什么？说出一些集合框架的优点？&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;img class="" data-ratio="0.41541353383458646" data-src="https://pangyd.com/uploads/2017/10/74c10f869f038762.jpeg" data-type="jpeg" data-w="532" height="221" width="532" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-fail="0">&lt;/p>&lt;p style="text-align: justify">&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>2.&lt;/span>&lt;span>集合框架中的泛型有什么优点？&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;img class="" data-ratio="0.3899782135076253" data-src="https://pangyd.com/uploads/2017/10/74c10f869f038762.jpeg" data-type="jpeg" data-w="459" height="179" width="459" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-fail="0">&lt;/p>&lt;p style="text-align: justify">&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>3.Java集合框架的基础接口有哪些？&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;img class="" data-ratio="0.6123348017621145" data-src="https://pangyd.com/uploads/2017/10/74c10f869f038762.jpeg" data-type="jpeg" data-w="454" height="278" width="454" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-fail="0">&lt;/p>&lt;p style="text-align: justify">&lt;span>　&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>4.为何Collection不从Cloneable和Serializable接口继承？&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;img class="" data-ratio="0.6563876651982379" data-src="https://pangyd.com/uploads/2017/10/74c10f869f038762.jpeg" data-type="jpeg" data-w="454" height="298" width="454" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-fail="0">&lt;/p>&lt;p style="text-align: justify">&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>5.为何Map接口不继承Collection接口？&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;img class="" data-ratio="0.3356009070294785" data-src="https://pangyd.com/uploads/2017/10/74c10f869f038762.jpeg" data-type="jpeg" data-w="441" height="148" width="441" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-fail="0">&lt;/p>&lt;p style="text-align: center">&lt;img class="" data-ratio="0.4796875" data-src="https://pangyd.com/uploads/2017/10/74c10f869f038762.jpeg" data-type="jpeg" data-w="640" height="378" width="787" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-fail="0">&lt;/p></description></item><item><title>Java字符串的10大热点问题盘点</title><link>https://pangyd.com/post/139-java10/</link><pubDate>Wed, 18 Oct 2017 20:04:33 +0800</pubDate><guid>https://pangyd.com/post/139-java10/</guid><description>&lt;p style="text-align: center">&lt;img data-s="300,640" data-type="jpeg" data-src="https://pangyd.com/uploads/2017/10/74c10f869f038762.jpg" data-copyright="0" class="" data-ratio="0.6661538461538462" data-w="650" data-backw="556" data-backh="370" width="100%" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-fail="0">&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;br>&lt;/p>&lt;p>&lt;span>下面我为大家总结了10条Java开发者经常会提的关于Java字符串的问题，如果你也是Java初学者，仔细看看吧：&lt;/span>&lt;/p>&lt;h2>&lt;span>1、如何比较字符串，应该用”==”还是equals()？&lt;/span>&lt;/h2>&lt;p>&lt;span>总的来说，”==”是用来比较字符串的引用地址，而equals()才是比较字符串的值。两个值相同的字符串用”==”比较结果有可能是false，而用equals()则一定为true。除非两个字符串是同一个new出来的对象，不然比较字符串值是否相同应该要用equals()。&lt;/span>&lt;/p>&lt;h2>&lt;span>2、对那些安全敏感的信息，为什么用char[]存储要优于String？&lt;/span>&lt;/h2>&lt;p>&lt;span>String是不可变的，这就意味着它一旦被创建，就将永久驻留在内存中，直到垃圾回收器将其回收为止。然而用数组存储方式，你可以明确地改变数组中的元素，因此用数组方式，安全信息将有可能不存在系统内存的任何地方。&lt;/span>&lt;/p>&lt;h2>&lt;span>3、能否用字符串来声明switch语句？&lt;/span>&lt;/h2>&lt;p>&lt;span>JAVA 7及以后的版本是支持的。在JDK 7中，允许你使用字符串做switch语句的比较条件。jdk 6以前的版本，不能这样使用：&lt;/span>&lt;/p>&lt;pre class="">//&amp;nbsp;java&amp;nbsp;7&amp;nbsp;only!switch&amp;nbsp;(str.toLowerCase())&amp;nbsp;{&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&amp;nbsp;"a":&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;value&amp;nbsp;=&amp;nbsp;1;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&amp;nbsp;"b":&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;value&amp;nbsp;=&amp;nbsp;2;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;&lt;br>}&lt;/pre>&lt;h2>&lt;span>4、如何将字符串转换成数字int类型？&lt;/span>&lt;/h2>&lt;pre class="">int&amp;nbsp;n&amp;nbsp;=&amp;nbsp;Integer.parseInt("10");&lt;/pre>&lt;p>&lt;span>很简单，但却会经常用到，也很容易被忽略。&lt;/span>&lt;/p>&lt;h2>&lt;span>5、如何用空格字符来分割字符串？&lt;/span>&lt;/h2>&lt;p>&lt;span>我们可以很方便地用正则表达式来分割字符串，”\s”表示空格字符，比如” “, “\t”, “\r”, “\n”&lt;/span>&lt;/p>&lt;pre class="">String[]&amp;nbsp;strArray&amp;nbsp;=&amp;nbsp;aString.split("\\s+");&lt;/pre>&lt;h2>&lt;span>6、substring()方法究竟是什么？&lt;/span>&lt;/h2>&lt;p>&lt;span>在jdk 6中，substring()方法在原来字符串中提供了一个截取字符的窗口，它并没有创建一个新的String实例。如果你想创建新的字符数组，你可以在substring()后加一个空字符，就像这样：&lt;/span>&lt;/p>&lt;pre class="">str.substring(m,&amp;nbsp;n)&amp;nbsp;+&amp;nbsp;""&lt;/pre>&lt;p>&lt;span>这样就会创建一个新的String实例，上面的方法有时候可以让你的程序运行速度更快，因为垃圾回收器可以将没用的大字符串回收走，并保留其子字符串。&lt;/span>&lt;/p>&lt;h2>&lt;span>7、String、StringBuilder和StringBuffer哪个更优？&lt;/span>&lt;/h2>&lt;p>&lt;span>String和StringBuilder：StringBuilder是可变的，也就是说用StringBuilder创建的字符串你可以随时改变它。StringBuilder和StringBuffer：StringBuffer是同步的，它是线程安全（thread-safe）的，但效率要比StringBuilder差得多。&lt;/span>&lt;/p>&lt;h2>&lt;span>8、如何重复输出字符串？&lt;/span>&lt;/h2>&lt;p>&lt;span>在Python中，我们只需要为字符串乘上一个数字就可以重复输出该字符串了。然而在Java中，我们可以用StringUtils的repeat()方法来实现，StringUtils是Apache公共语言库的其中一个类库成员。&lt;/span>&lt;/p>&lt;pre class="">String&amp;nbsp;str&amp;nbsp;=&amp;nbsp;"abcd";String&amp;nbsp;repeated&amp;nbsp;=&amp;nbsp;StringUtils.repeat(str,3);//abcdabcdabcd&lt;/pre>&lt;h2>&lt;span>9、如何将字符串转换成日期类型？&lt;/span>&lt;/h2>&lt;p>&lt;span>你可以按以下方法来做，代码如下：&lt;/span>&lt;/p>&lt;pre class="">String&amp;nbsp;str&amp;nbsp;=&amp;nbsp;"Sep&amp;nbsp;17,&amp;nbsp;2013";Date&amp;nbsp;date&amp;nbsp;=&amp;nbsp;new&amp;nbsp;SimpleDateFormat("MMMM&amp;nbsp;d,&amp;nbsp;yy",&amp;nbsp;Locale.ENGLISH).parse(str);&lt;br>System.out.println(date);//Tue&amp;nbsp;Sep&amp;nbsp;17&amp;nbsp;00:00:00&amp;nbsp;EDT&amp;nbsp;2013&lt;/pre>&lt;h2>&lt;span>10、如何统计指定字符在字符串中出现的频率&lt;/span>&lt;/h2>&lt;p>&lt;span>同样我们利用了Apache公共语言库中的StringUtils，代码如下：&lt;/span>&lt;/p>&lt;pre class="">int&amp;nbsp;n&amp;nbsp;=&amp;nbsp;StringUtils.countMatches("11112222",&amp;nbsp;"1");&lt;br>System.out.println(n);&lt;/pre></description></item><item><title>Java程序员面试时需要注意的几点</title><link>https://pangyd.com/post/138-java/</link><pubDate>Tue, 17 Oct 2017 21:03:12 +0800</pubDate><guid>https://pangyd.com/post/138-java/</guid><description>&lt;p>给自己写一份非常专业的简历&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>如果你想增加自己的入选机会，那最好还是花点钱制作一份专业的简历。相较于你将来可能得到的巨大收获，这真的只是一个小小的投资。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>研究面试公司&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>如果你对自己所要面试的公司了如指掌，甚至对官网上的一些博客或视频能够侃侃而谈，相信一定能更能给面试官留下深刻印象，当然，在这过程中也要注意，意见的发表要把握尺度，自信而不自傲！&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>永远不要撒谎&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>最糟糕的就是在面试的时候撒谎。知之为知之，不知为不知，如果你确实不知道，千万不要自作聪明来编造问题的答案。相反，你应该诚实的说，你不知道或者你并不是百分百的肯定，但是你愿意尝试一下，然后再讲讲自己的想法。讲完后也可以问面试官正确答案是什么，以显示你对此非常感兴趣。&lt;/p>&lt;p>&amp;nbsp;&lt;/p>&lt;p>一般来讲，面试官问的问题大都都是他们知道的问题如果你滥竽充数抱着侥幸心理，一旦被发现，面试官马上会质疑你的人品。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>学会解决算法问题&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>这是每一个开发人员都应该具备的重要技能，而且真要掌握起来也并非那么难。&lt;/p>&lt;p>&amp;nbsp;&lt;/p>&lt;p>在很多面试中，都会有这样的问题，要求你在白板或者电脑上解决软件编程问题，但是许多程序员，即使是那些非常优秀的程序员，都会一下子大脑一片空白，完全理不出思路来。如果你能花时间学会如何解决这种类型的面试问题，那么下次再碰到这种场景，就不会这么紧张了。我们会紧张其实和怯场无关，主要是因为我们不熟悉这些问题，也没有自信能解决这种问题。在这方面建立起自信之后，你就再也不会紧张了。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>活力洋溢地回答问题&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>只用一个字或者一句话，照本宣科平平无奇地回答问题，或许在技术上是正确的，但是你忘了应该借此机会好好展示自己的激情——这才是一个开发人员能带给团队的最大正能量。&lt;/p></description></item><item><title>【概念】每个程序员都应该知道的基础数论</title><link>https://pangyd.com/post/137/</link><pubDate>Mon, 16 Oct 2017 20:05:21 +0800</pubDate><guid>https://pangyd.com/post/137/</guid><description>&lt;p>这篇文章讨论了数论中每个程序员都应该知道的几个重要概念。本文的内容既不是对数论的入门介绍，也不是针对数论中任何特定算法的讨论，而只是想要做为数论的一篇参考。如果读者想要获取关于数论的更多细节，文中也提供了一些外部的参考文献(大多数来自于 Wikipedia 和 Wolfram )。&lt;/p>&lt;p>每个程序员都应该知道的基础数论&lt;/p>&lt;p>0. 皮亚诺公理&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>整个算术规则都是建立在 5 个基本公理基础之上的，这 5 个基本公理被称为皮亚诺公理。皮亚诺公理定义了自然数所具有的特性，具体如下：&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>0是自然数;&lt;/p>&lt;p>每个自然数都有一个后续自然数;&lt;/p>&lt;p>0不是任何自然数的后续自然数;&lt;/p>&lt;p>不同自然数的后续自然数不同;&lt;/p>&lt;p>如果集合S包含了数字0，并且包含S中每一个数字的后续自然数，那么集合S就包含了所有的自然数。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>上述第5个公理也被称为“数学归纳法的基础”。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>通常，除了我们想要证明其他算术定理的情况，我们很少直接使用上述公理。但作为算术的基石，这些公理是值得我们去了解的。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>1. 算术基本定理和除法运算法则&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>正如这个定理的名称所言，算术基本定理是数论中所有概念的核心。算术基本定理含义如下：任何一个大于1的整数都可以以某种特定的方式写成质数的乘积的形式(这种特定方式取决于乘积中质数的顺序)。例如，18 = 2 * 9, 1755 = 33 *5 * 13. 这个定理在几乎所有的数论运算法则中都扮演着十分重要的角色，例如求一个数的质数因子、最大公约数、除数的和等等。想要证明这个定理其实很简单，实际上它是欧几里得第一个定理的一个推论(下面小节会讨论到)。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>除法运算法则含义是说：给定两个整数a，b(b不等于0)，那么存在两个整数q和r使得下面的等式成立：&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>a = bq + r， 0 &amp;lt;= r &amp;lt; b&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>通常我们把q称为商，而把r称为余数。如果r = 0，那么我就说b整除a，并且表示为：b | a.&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>2. 欧几里得定理&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>数学中两个重要定理，被称为“欧几里德的第一定理(或欧几里德的引理)”和“欧几里德的第二定理(通常简称为”欧几里德定理“)，内容如下：&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>第一定理：p|ab =&amp;gt; p|a or p|b。该定理的直接结论就是算术基本定理。&lt;/p>&lt;p>&lt;br>&lt;/p></description></item><item><title>服务端 I/O 性能大比拼：Node、PHP、Java 和 Go</title><link>https://pangyd.com/post/134-i-o-nodephpjava-go/</link><pubDate>Sat, 14 Oct 2017 19:47:46 +0800</pubDate><guid>https://pangyd.com/post/134-i-o-nodephpjava-go/</guid><description>&lt;p>理解应用程序的输入/输出（I/O）模型，意味着其在计划处理负载与残酷的实际使用场景之间的差异。若应用程序比较小，也没有服务于很高的负载，也许它影响甚微。但随着应用程序的负载逐渐上涨，采用错误的I/O模型有可能会让你到处踩坑，伤痕累累。&lt;/p>&lt;p>正如大部分存在多种解决途径的场景一样，重点不在于哪一种途径更好，而是在于理解如何进行权衡。让我们来参观下I/O的景观，看下可以从中窃取点什么。&lt;/p>&lt;p>&lt;img data-src="https://pangyd.com/uploads/2017/10/74c10f869f038762.jpg" class="" data-ratio="1" data-w="1280" data-type="jpeg" src="https://pangyd.com/uploads/2017/10/74c10f869f038762.jpg" data-fail="0">&lt;/p>&lt;p>在这篇文章，我们将会结合Apache分别比较Node，Java，Go，和PHP，讨论这些不同的语言如何对他们的I/O进行建模，各个模型的优点和缺点，并得出一些初步基准的结论。如果关心你下一个Web应用的I/O性能，那你就找对文章了。&lt;/p>&lt;h2>I/O基础知识：快速回顾&lt;/h2>&lt;p>为了理解与I/O密切相关的因素，必须先来回顾在操作系统底层的概念。虽然不会直接处理这些概念的大部分，但通过应用程序的运行时环境你一直在间接地处理他们。而关键在于细节。&lt;/p>&lt;h3>系统调用&lt;/h3>&lt;p>首先，我们有系统调用，它可以描述成这样：&lt;/p>&lt;ul class="list-paddingleft-2">&lt;li>&lt;p>你的程序（在“用户区域”，正如他们所说的）必须让操作系统内核在它自身执行I/O操作。&lt;/p>&lt;/li>&lt;li>&lt;p>“系统调用”（syscall）意味着你的程序要求内核做某事。不同的操作系统，实现系统调用的细节有所不同，但基本的概念是一样的。这将会有一些特定的指令，把控制权从你的程序转交到内核（类似函数调用但有一些专门用于处理这种场景的特殊sauce）。通常来说，系统调用是阻塞的，意味着你的程序需要等待内核返回到你的代码。&lt;/p>&lt;/li>&lt;li>&lt;p>内核在我们所说的物理设备（硬盘、网卡等）上执行底层的I/O操作，并回复给系统调用。在现实世界中，内核可能需要做很多事情才能完成你的请求，包括等待设备准备就绪，更新它的内部状态等，但作为一名应用程序开发人员，你可以不用关心这些。以下是内核的工作情况。&lt;/p>&lt;/li>&lt;/ul>&lt;p>&lt;img data-src="https://pangyd.com/uploads/2017/10/74c10f869f038762.jpg" class="" data-ratio="1" data-w="1280" data-type="jpeg" src="https://pangyd.com/uploads/2017/10/74c10f869f038762.jpg" data-fail="0">&lt;/p>&lt;h3>阻塞调用与非阻塞调用&lt;/h3>&lt;p>好了，我刚刚在上面说系统调用是阻塞的，通常来说这是对的。然而，有些调用被分类为“非阻塞”，意味着内核接收了你的请求后，把它放进了队列或者缓冲的某个地方，然后立即返回而并没有等待实际的I/O调用。所以它只是“阻塞”了一段非常短的时间，短到只是把你的请求入列而已。&lt;/p>&lt;p>这里有一些有助于解释清楚的（Linux系统调用）例子：&lt;code>-read()&lt;/code>是阻塞调用——你传给它一个文件句柄和一个存放所读到数据的缓冲，然后此调用会在当数据好后返回。注意这种方式有着优雅和简单的优点。&lt;code>-epoll_create()&lt;/code>，&lt;code>epoll_ctl()&lt;/code>，和&lt;code>epoll_wait()&lt;/code>这些调用分别是，让你创建一组用于侦听的句柄，从该组添加/删除句柄，和然后直到有活动时才阻塞。这使得你可以通过一个线程有效地控制一系列I/O操作。如果需要这些功能，这非常棒，但也正如你所看到的，使用起来当然也相当复杂。&lt;/p>&lt;p>理解这里分时差异的数量级是很重要的。如果一个CPU内核运行在3GHz，在没有优化的情况下，它每秒执行30亿次循环（或者每纳秒3次循环）。非阻塞系统调用可能需要10纳秒这样数量级的周期才能完成——或者“相对较少的纳秒”。对于正在通过网络接收信息的阻塞调用可能需要更多的时间——例如200毫秒（0.2秒）。例如，假设非阻塞调用消耗了20纳秒，那么阻塞调用消耗了200,000,000纳秒。对于阻塞调用，你的程序多等待了1000万倍的时间。&lt;/p>&lt;p>&lt;img data-src="https://pangyd.com/uploads/2017/10/74c10f869f038762.jpg" class="" data-ratio="1" data-w="1280" data-type="jpeg" src="https://pangyd.com/uploads/2017/10/74c10f869f038762.jpg" data-fail="0">&lt;/p>&lt;p>内核提供了阻塞I/O（“从网络连接中读取并把数据给我”）和非阻塞I/O（“当这些网络连接有新数据时就告诉我”）这两种方法。而使用何种机制，对应调用过程的阻塞时间明显长度不同。&lt;/p>&lt;h3>调度&lt;/h3>&lt;p>接下来第三件关键的事情是，当有大量线程或进程开始阻塞时怎么办。&lt;/p>&lt;p>出于我们的目的，线程和进程之间没有太大的区别。实际上，最显而易见的执行相关的区别是，线程共享相同的内存，而每个进程则拥有他们独自的内存空间，使得分离的进程往往占据了大量的内存。但当我们讨论调度时，它最终可归结为一个事件清单（线程和进程类似），其中每个事件需要在有效的CPU内核上获得一片执行时间。如果你有300个线程正在运行并且运行在8核上，那么你得通过每个内核运行一段很短的时间然后切换到下一个线程的方式，把这些时间划分开来以便每个线程都能获得它的分时。这是通过“上下文切换”来实现的，使得CPU可以从正在运行的某个线程/进程切换到下一个。&lt;/p>&lt;p>这些上下文切换有一定的成本——它们消耗了一些时间。在快的时候，可能少于100纳秒，但是根据实现的细节，处理器速度/架构，CPU缓存等，消耗1000纳秒甚至更长的时间也并不罕见。&lt;/p>&lt;p>线程（或者进程）越多，上下文切换就越多。当我们谈论成千上万的线程，并且每一次切换需要数百纳秒时，速度将会变得非常慢。&lt;/p>&lt;p>然而，非阻塞调用本质上是告诉内核“当你有一些新的数据或者这些连接中的任意一个有事件时才调用我”。这些非阻塞调用设计于高效地处理大量的I/O负载，以及减少上下文切换。&lt;/p>&lt;p>到目前为止你还在看这篇文章吗？因为现在来到了有趣的部分：让我们来看下一些流利的语言如何使用这些工具，并就在易用性和性能之间的权衡作出一些结论……以及其他有趣的点评。&lt;/p>&lt;p>请注意，虽然在这篇文章中展示的示例是琐碎的（并且是不完整的，只是显示了相关部分的代码），但数据库访问，外部缓存系统（memcache等全部）和需要I/O的任何东西，都以执行某些背后的I/O操作而结束，这些和展示的示例一样有着同样的影响。同样地，对于I/O被描述为“阻塞”（PHP，Java）这样的情节，HTTP请求与响应的读取与写入本身是阻塞的调用：再一次，更多隐藏在系统中的I/O及其伴随的性能问题需要考虑。&lt;/p>&lt;p>为项目选择编程语言要考虑的因素有很多。当你只考虑性能时，要考虑的因素甚至有更多。但是，如果你关注的是程序主要受限于I/O，如果I/O性能对于你的项目至关重要，那这些都是你需要了解的。“保持简单”的方法：PHP。&lt;/p>&lt;p>回到90年代的时候，很多人穿着匡威鞋，用Perl写着CGI脚本。随后出现了PHP，很多人喜欢使用它，它使得制作动态网页更为容易。&lt;/p>&lt;p>PHP使用的模型相当简单。虽然有一些变化，但基本上PHP服务器看起来像：&lt;/p>&lt;p>HTTP请求来自用户的浏览器，并且访问了你的Apache网站服务器。Apache为每个请求创建一个单独的进程，通过一些优化来重用它们，以便最大程度地减少其需要执行的次数（创建进程相对来说较慢）。Apache调用PHP并告诉它在磁盘上运行相应的&lt;code>.php&lt;/code>文件。PHP代码执行并做一些阻塞的I/O调用。若在PHP中调用了&lt;code>file_get_contents()&lt;/code>，那在背后它会触发&lt;code>read()&lt;/code>系统调用并等待结果返回。&lt;/p>&lt;p>当然，实际的代码只是简单地嵌在你的页面中，并且操作是阻塞的：&lt;/p>&lt;p>&lt;img data-s="300,640" data-type="png" data-src="https://pangyd.com/uploads/2017/10/74c10f869f038762.jpg" class="" data-ratio="0.45230263157894735" data-w="608" src="https://pangyd.com/uploads/2017/10/74c10f869f038762.jpg" data-fail="0">&lt;/p>&lt;p>关于它如何与系统集成，就像这样：&lt;/p>&lt;p>&lt;img data-src="https://pangyd.com/uploads/2017/10/74c10f869f038762.jpg" class="" data-ratio="1" data-w="1280" data-type="jpeg" src="https://pangyd.com/uploads/2017/10/74c10f869f038762.jpg" data-fail="0">&lt;/p>&lt;p>相当简单：一个请求，一个进程。I/O是阻塞的。优点是什么呢？简单，可行。那缺点是什么呢？同时与20,000个客户端连接，你的服务器就挂了。由于内核提供的用于处理大容量I/O（epoll等）的工具没有被使用，所以这种方法不能很好地扩展。更糟糕的是，为每个请求运行一个单独的过程往往会使用大量的系统资源，尤其是内存，这通常是在这样的场景中遇到的第一件事情。&lt;/p>&lt;p>注意：Ruby使用的方法与PHP非常相似，在广泛而普遍的方式下，我们可以将其视为是相同的。&lt;/p>&lt;h2>多线程的方式：Java&lt;/h2>&lt;p>所以就在你买了你的第一个域名的时候，Java来了，并且在一个句子之后随便说一句“dot com”是很酷的。而Java具有语言内置的多线程（特别是在创建时），这一点非常棒。&lt;/p>&lt;p>大多数Java网站服务器通过为每个进来的请求启动一个新的执行线程，然后在该线程中最终调用作为应用程序开发人员的你所编写的函数。&lt;/p>&lt;p>在Java的Servlet中执行I/O操作，往往看起来像是这样：&lt;/p>&lt;p>&lt;img data-s="300,640" data-type="png" data-src="https://pangyd.com/uploads/2017/10/74c10f869f038762.jpg" class="" data-ratio="0.3900804289544236" data-w="746" src="https://pangyd.com/uploads/2017/10/74c10f869f038762.jpg" data-fail="0">&lt;/p>&lt;p>由于我们上面的&lt;code>doGet&lt;/code>方法对应于一个请求并且在自己的线程中运行，而不是每次请求都对应需要有自己专属内存的单独进程，所以我们会有一个单独的线程。这样会有一些不错的优点，例如可以在线程之间共享状态、共享缓存的数据等，因为它们可以相互访问各自的内存，但是它如何与调度进行交互的影响，仍然与前面PHP例子中所做的内容几乎一模一样。每个请求都会产生一个新的线程，而在这个线程中的各种I/O操作会一直阻塞，直到这个请求被完全处理为止。为了最小化创建和销毁它们的成本，线程会被汇集在一起，但是依然，有成千上万个连接就意味着成千上万个线程，这对于调度器是不利的。&lt;/p></description></item><item><title>Kotlin 将超越 Java 成为 Android 开发的第一语言？</title><link>https://pangyd.com/post/133-kotlin-java-android/</link><pubDate>Sat, 14 Oct 2017 00:08:50 +0800</pubDate><guid>https://pangyd.com/post/133-kotlin-java-android/</guid><description>&lt;p>Realm 公司提供了一款备受移动开发者欢迎的实时数据库，在调查了大约十万名活跃的开发者后，Realm 发现在今年 5 月份谷歌 I/O 大会之前用 Java 编写的 Android 应用中有 20% 正在用 Kotlin 进行重写。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>根据调查数据，Realm 表示到 2018 年底，在 Android 开发领域，Kotlin 将超越 Java，成为开发 Android 应用的第一语言。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>该公司于周二在官网上公布了其调查结果，它的惯例是每季度发布一次调查结果。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>￼&lt;/p>&lt;p>当然，这些数据不是特别适用于广泛的 Java 开发者群体，甲骨文最近估计这个群体有 1200 万人。不过数据表明，Android 生态系统确实处于迅速变化之中。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>Kotlin 是一门面向 Java 虚拟机(JVM)、Android、JavaScript 和 Native 的开源语言，它于 2011 年由 JetBrains 推出，去年发布 1.0 版本，今年谷歌宣布它成为 Android 领域官方支持的开发语言。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>JetBrains 表示，Kotlin 比 Java 更简洁，所需编写的代码行大概比 Java 少 40%。此外，类型安全方面 Kotlin 也比 Java 好，并支持函数式编程。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>Realm 的数据显示，2016年9月，Kotlin 占 Android 开发的 5.1％，而 Java 的占 94.9％。一年之后，这个比例变成 Kotlin 升至 14.3％，而 Java 则降为 85.7％。这个变化相当大。&lt;/p></description></item><item><title>JVM 语言的兴衰史</title><link>https://pangyd.com/post/132-jvm/</link><pubDate>Thu, 12 Oct 2017 23:38:25 +0800</pubDate><guid>https://pangyd.com/post/132-jvm/</guid><description>&lt;p>不管什么时候，都会有一些预测 Java 覆灭的帖子出现。但有趣的是，这些帖子从不写预言成真的日期。说实话，它们说的都算正确，因为这是每一种语言的最终命运都是：覆灭湮没，准确地说是越来越少地被利用到新项目中。问题是：最后谁会取代它们呢？&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>上周我们在 InfoQ 一篇同样类型的文章。至少，这篇文章说出来这个语言可能的替代者 Kotlin。这让我对 JVM 的语言现状和趋势有了许多思考：注意，语言的趋势与每个语言的技术优点和缺点无关。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>我于 2001 年年底开始做 Java 开发，当时，Java 是真的很酷。每一个新开发者都想使用所谓的新技术：无论是 .NET 还是 Java，而有经验一些的开发者使用的是 COBOL。我在学校学习了 C 和 C++，所以 Java 内存管理对于我来说非常简单。我对 Java 很满意，但并不是每个人都这么认为。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>Groovy 诞生于 2003 年。但我不记得我是什么时候开始学习它的。而实际上：使用它后我不再需要一门脚本语言了。在具有多个开发团队并长时间开发企业级应用程序的背景之下，静态类型相比动态类型拥有巨大优势。尤其在进行产品测试以检查类型系统时。我唯一需要创建脚本的时候，是作为 WebSphere 管理员时：选择 Python 还是 TCL。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>一年之后，Scala在2004年被我接受。 我不记得是什么时候以及是怎样知道Scala的，但那时候确实是很晚了。与Groovy相反，我决定试试它。主要的理由是我长期以来对创建“更好”的代码（更好的可读性和可维护性）感兴趣。Scala是静态类型的，它更像我正在寻找的东西。我报了Coursera课程Scala中的函数式编程原理。它有三个主要的影响：&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>它让我质疑我写Java代码的方式。 例如，为什么当我设计类时要自动生成getter和setter方法？&lt;/p>&lt;p>对大多数开发者来说，我觉得Scala很容易写出缺乏可读性的的代码——包括我。&lt;/p>&lt;p>我开始寻找其他替代语言。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>在 Groovy 和 Scala 之后，第二代（如果你把 Java 也算做第一代的话，则是第三代）JVM 语言包括：&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>JetBrains Kotlin&lt;/p>&lt;p>Red Hat Ceylon&lt;/p>&lt;p>Eclipse eXtend&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>大致浏览一遍后，我确信他们没有太多的吸引力，不值得我投入时间。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>几年前，我决定自学基本的 Android 开发，以便能够了解移动开发者的开发环境。好家伙，即使有多年开发 Java EE 和 Spring 应用程序的经验，但它还真给我一个惊喜了 - 还不是愉快的那种。这就像回到过去十年前那样的开发体验，Android &amp;nbsp;API 非常低级，更别说在本地测试应用程序。经过快速的搜索相关信息，我发现 Kotlin 在很多地方被提到，所以最后决定试一试。我立即爱上 Kotlin 了，得亏它的扩展功能，我可以将现有的垃圾 API 改进得更好，甚至更优雅。我开始更多的挖掘这门语言，并开始在服务器端项目中使用 Kotlin。然后，Spring 框架宣布了与 Kotlin 的整合。然后在 Google I/O 大会上，Google 也宣布在 Android 开发中官方支持 Kotlin。&lt;/p></description></item><item><title>编程语言 10 月排行榜：Java/C/C++ 固守前三，Swift/GO持续下降，惨！</title><link>https://pangyd.com/post/131-10-java-c-c-swift-go/</link><pubDate>Wed, 11 Oct 2017 20:02:20 +0800</pubDate><guid>https://pangyd.com/post/131-10-java-c-c-swift-go/</guid><description>&lt;section class="" powered-by="xiumi.us">&lt;section class="">&lt;section class="">&lt;section class="" powered-by="xiumi.us">&lt;section class="">&lt;section class="">&lt;p>&lt;span>近期，TIOBE公布了2017年10月编程语言指数排行榜：&lt;/span>&lt;/p>&lt;p>&lt;span>Java、C、C++依旧&lt;/span>&lt;span>排名前三，三巨头地位持续15年来一直不变。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>排名第四和第五的是&lt;/span>C# 和 Python 。&lt;/span>&lt;/p>&lt;p>&lt;span>而Swift、Objective-C、Visual Basic、Go处于持续下降的趋势。&lt;/span>&lt;/p>&lt;/section>&lt;/section>&lt;/section>&lt;/section>&lt;/section>&lt;/section>&lt;p>&lt;/p>&lt;p>&lt;p>&lt;/p>&lt;/p>&lt;section class="" powered-by="xiumi.us" style="text-align: start">&lt;section class="">&lt;section class="">&lt;p>&lt;br>&lt;/p>&lt;p>&lt;strong>&lt;span>&amp;nbsp;2017 年 10&amp;nbsp;月 Top 20 语言&lt;/span>&lt;/strong>&lt;br>&lt;/p>&lt;p style="text-align: center">&lt;img class="" data-ratio="0.8067940552016986" data-s="300,640" data-src="https://pangyd.com/uploads/2017/10/74c10f869f038762.jpg" data-type="png" data-w="942" width="auto" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-fail="0">&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>看到这个排行榜，不少养码人对于C#的排名表示欣慰。&lt;/p>&lt;p>&lt;strong>&lt;span>养码人A：&lt;/span>&lt;/strong>&lt;br>我大C#必将一统天下&lt;img class="" data-ratio="1" data-src="https://pangyd.com/uploads/2017/10/b7c4a161038a4b1b.png" data-w="20" width="20px" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-fail="0">&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;strong>&lt;span>养码人B：&lt;/span>&lt;/strong>&lt;/p>&lt;p>C#这么靠前，生命力不错啊。&lt;img data-src="https://pangyd.com/uploads/2017/10/74c10f869f038762.jpg" data-type="png" class="" data-ratio="0.5769230769230769" data-w="52" src="https://pangyd.com/uploads/2017/10/74c10f869f038762.jpg" data-fail="0">&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>&lt;strong>养码人C：&lt;/strong>&lt;/span>&lt;/p>&lt;p>貌似目前很多手游都用C#&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p style="text-align: center">&lt;img data-src="https://pangyd.com/uploads/2017/10/74c10f869f038762.jpg" data-type="png" class="" data-ratio="0.825531914893617" data-w="235" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-fail="0">&lt;/p>&lt;p style="text-align: center">&lt;br>&lt;/p>&lt;p style="text-align: center">&lt;br>&lt;/p>&lt;p>再说回Swift和Go。&lt;strong>在今年年初，Swift 语言的 TIOBE 指数最高达到 2.3%，排在&lt;span>第 10 位&lt;/span>。不过 Swift 目前降到&lt;span>第 16 位&lt;/span>，并且其热度每月都在下降。&lt;/strong>&lt;/p></description></item><item><title>死磕 Java 并发 ：Java 内存模型之 happens-before</title><link>https://pangyd.com/post/130-java-java-happens-before/</link><pubDate>Tue, 10 Oct 2017 22:10:06 +0800</pubDate><guid>https://pangyd.com/post/130-java-java-happens-before/</guid><description>&lt;p>那么我们正确使用同步、锁的情况下，线程A修改了变量a何时对线程B可见？&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>我们无法就所有场景来规定某个线程修改的变量何时对其他线程可见，但是我们可以指定某些规则，这规则就是happens-before，从JDK 5 开始，JMM就使用happens-before的概念来阐述多线程之间的内存可见性。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>在JMM中，如果一个操作执行的结果需要对另一个操作可见，那么这两个操作之间必须存在happens-before关系。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>happens-before原则非常重要，它是判断数据是否存在竞争、线程是否安全的主要依据，依靠这个原则，我们解决在并发环境下两操作之间是否可能存在冲突的所有问题。下面我们就一个简单的例子稍微了解下happens-before ；&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>i = 1; &amp;nbsp; &amp;nbsp; &amp;nbsp; //线程A执行&lt;/p>&lt;p>j = i ; &amp;nbsp; &amp;nbsp; &amp;nbsp;//线程B执行&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>j 是否等于1呢？假定线程A的操作（i = 1）happens-before线程B的操作（j = i）,那么可以确定线程B执行后j = 1 一定成立，如果他们不存在happens-before原则，那么j = 1 不一定成立。这就是happens-before原则的威力。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>happens-before原则定义如下：&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>如果一个操作happens-before另一个操作，那么第一个操作的执行结果将对第二个操作可见，而且第一个操作的执行顺序排在第二个操作之前。&lt;/p>&lt;p>两个操作之间存在happens-before关系，并不意味着一定要按照happens-before原则制定的顺序来执行。如果重排序之后的执行结果与按照happens-before关系来执行的结果一致，那么这种重排序并不非法。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>下面是happens-before原则规则：&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>程序次序规则：一个线程内，按照代码顺序，书写在前面的操作先行发生于书写在后面的操作；&lt;/p>&lt;p>锁定规则：一个unLock操作先行发生于后面对同一个锁额lock操作；&lt;/p>&lt;p>volatile变量规则：对一个变量的写操作先行发生于后面对这个变量的读操作；&lt;/p>&lt;p>传递规则：如果操作A先行发生于操作B，而操作B又先行发生于操作C，则可以得出操作A先行发生于操作C；&lt;/p>&lt;p>线程启动规则：Thread对象的start()方法先行发生于此线程的每个一个动作；&lt;/p>&lt;p>线程中断规则：对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件的发生；&lt;/p>&lt;p>线程终结规则：线程中所有的操作都先行发生于线程的终止检测，我们可以通过Thread.join()方法结束、Thread.isAlive()的返回值手段检测到线程已经终止执行；&lt;/p>&lt;p>对象终结规则：一个对象的初始化完成先行发生于他的finalize()方法的开始；&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>我们来详细看看上面每条规则（摘自《深入理解Java虚拟机第12章》）：&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>程序次序规则：一段代码在单线程中执行的结果是有序的。注意是执行结果，因为虚拟机、处理器会对指令进行重排序（重排序后面会详细介绍）。虽然重排序了，但是并不会影响程序的执行结果，所以程序最终执行的结果与顺序执行的结果是一致的。故而这个规则只对单线程有效，在多线程环境下无法保证正确性。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>锁定规则：这个规则比较好理解，无论是在单线程环境还是多线程环境，一个锁处于被锁定状态，那么必须先执行unlock操作后面才能进行lock操作。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>volatile变量规则：这是一条比较重要的规则，它标志着volatile保证了线程可见性。通俗点讲就是如果一个线程先去写一个volatile变量，然后一个线程去读这个变量，那么这个写操作一定是happens-before读操作的。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>传递规则：提现了happens-before原则具有传递性，即A happens-before B , B happens-before C，那么A happens-before C&lt;/p></description></item><item><title>Java知识点归纳-J2EE 、 Web 部分</title><link>https://pangyd.com/post/129-java-j2ee-web/</link><pubDate>Mon, 09 Oct 2017 22:07:37 +0800</pubDate><guid>https://pangyd.com/post/129-java-j2ee-web/</guid><description>&lt;p>J2EE（Java2 Enterprise Edition） 刚出现时一般会用于开发企业内部的应用系统，特别是web应用，所以渐渐，有些人就会把J2EE和web模式画上了等号。但是其实 J2EE 里面并不仅仅是web，可以看到很多其中的规范都是通用的，目的是为了高效开发出健壮的服务企业业务模式的应用系统。J2EE中也是可以没有web界面的应用，而现在面向大众用户开发的网站往往也会使用到很多的J2EE的技术，所以J2EE和web开发的概念都是融合在了一起了。&lt;/p>&lt;p>笔者在JAVA开发刚入行的时候，也是做了不少web相关的项目，之后渐渐地web使用比较少了，现在web开发的技术日新月异，不过一些基础知识还是类似，所以也把这部分内容稍作整理，以期望可以给大家一些经验。&lt;/p>&lt;p>这次主要涉及到的两大块内容: Web相关的， J2EE相关的技术&lt;/p>&lt;p>Web部分:&lt;/p>&lt;p>脱离开各种语言，纯粹和 web相关的就是这些: HTML，CSS，JavaScript。哪怕你不用Java开发，用C#、PHP或者Python，这些内容都是通用，这里主要偏重一些基础知识。&lt;/p>&lt;p>HTTP协议，HTTPS协议&lt;/p>&lt;p>我觉得做Web开发，HTTP是基础中的基础。在一开始的时候，开发者可能对于这个内容了解不是非常深入，只是有个初步的概念，这个没有问题，可以先从了解，简单使用开始。 不过一旦有了一些web开发经验之后，你就需要把这块内容深入理解吃透。只知道简单概念，没有深入了解，可能并不会影响你开始上手做web开发，但是一旦涉及到一些性能调优、系统架构等工作，就需要你对HTTP有一个深入的了解，才能把工作做好。&lt;/p>&lt;p>对于HTTP请求， 我主要会关注以下内容:&lt;/p>&lt;p>&amp;nbsp;HTTP请求的模式: request/response&lt;/p>&lt;p>HTTP请求的方法：GET， POST， PUT，DELETE 等等&lt;/p>&lt;p>协议的具体格式: head + body&lt;/p>&lt;p>协议的各类返回码:1XX，2XX，3XX，4XX，5XX&lt;/p>&lt;p>Header中一些主要属性的含义和使用场景&lt;/p>&lt;p>HTTPS协议&lt;/p>&lt;p>Cookie的基本原理和使用场景&lt;/p>&lt;p>HTML， CSS&lt;/p>&lt;p>这是WEB开发的一个基础，如果公司有专门的前端开发人员，可能你就不需要做这块相关的内容。可能只需要准备一些服务，可以提供一些数据就行。不过要是公司没有专门的前端人员，那就需要你自己写简单的页面和简单的布局了。这种情况下，还是对HTML和CSS必须有个简单的了解才行。&lt;/p>&lt;p>HTML简单了解的话需要知道页面的结构，具体各个表单，标签的使用方法，CSS需要知道一些基本的选择器的编写和使用。但这也只能满足一些简单页面的要求。如果有更加复杂页面的开发需求，那对CSS+DIV的使用需要有更加深入的了解了，具体内容因为自己对这方面涉及不多，也不多说了，大家可以再找其他的参考资料。&lt;/p>&lt;p>JavaScript：&lt;/p>&lt;p>前端开发的语言，唯一的语言，就是JS。并且从中衍生出一个很优秀的框架jQuery。现在前端基本上只要有一点复杂度的，都会使用这两种技术。并且以jquery为基础，还有一些其他前台框架，提供了各种动态效果，还有表格，表单等一些常用的处理。近两年，AngularJS框架又开始火热起来，这个框架在前端实现了MVC的架构，给前端的开发带来了革命性的影响(但是不意味着所有的前端开发都应该要用这个)。这些都是很值得好好看一下。即便不是专攻前端开发的，但是对于这几个技术点，能够先了解一下基本情况，基本的原理，对于web开发来说，还是大有好处的。&lt;/p>&lt;p>Webservice&lt;/p>&lt;p>在现在的企业应用开发中，Webservice已经是个必备的工具了。在各个企业中，经过一段时间积累，会有很多不同种类的应用，这些应用可能都会使用不同的语言开发，并且需要相互之间的通讯。通讯的首选就是Webservice。前后台的交互，服务之间的交互，或者不同语言之间的交互，都可以使用Webservice这个技术。&lt;/p>&lt;p>Webservice的实现方式多种多样，两者共同点是大家都是以HTTP协议为基础的，都可以跨域，跨语言进行访问。&lt;/p>&lt;p>用的比较多的，一个是SOAP协议的方式。这是比较传统的webservice 的实现，这个协议比较重量级，发布者会将webservice以wsdl形式发布，调用者通过wsdl可以直接生成实体类等。对于调用者来说，“调用”这个步骤会更容易处理一些。不过SOAP形式也存在着消息量大，传输效率低等缺陷。SOAP协议本身的可选项比较多，比较复杂，各个属性设置略有差异会导致服务通讯的失败，需要在调试中需要花费更多的时间。&lt;/p>&lt;p>现在更加流行的是使用RESTFUL的Webservice。这种技术是简化了URL，或者说对URL做了一定格式的限定，同时配合上HTTP的各种method，包括有GET，POST，DELTE，PUT 等，来实现整体service的各种功能。一般传输的内容都是json格式的字符串。Restful的Webservice的优点在于这是一种更加轻量级的使用方式，传输效率更高，接口约定更加清晰，双方调试也会更加便利一些。缺点在于，json格式太灵活，所以双方都需要自行处理json中的各个参数。对于接口实体类的处理需要更多的逻辑和代码。&lt;/p>&lt;p>J2EE部分&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>JDBC(可以在J2SE中使用)&lt;/p>&lt;p>JDBC用于java和数据库交互。它是Java面向接口编程的一个典型实例：开发者使用JDBC的API进行开发，但是底层可以针对不同的数据库使用不同的JDBC驱动(由各个数据库供应商提供)。JDBC被归为了J2EE的规范中，但是在一般的java程序中也可以使用，而且也是几乎都会被直接或者间接使用（除非不用数据库）。这从侧面也说明了，其实J2EE企业开发和web开发并不是同一个概念，而是相互融合的。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>JDBC是Java中最原始，最纯粹，效率最高的访问数据库的方式，我们熟知的hibernate、 Mybatis等ORM框架都是在JDBC基础上做的封装。了解JDBC对于以后和数据库更好打交道会有着很大的用处。哪怕是一个java开发新手，你需要去学习Hibernate、Mybatis等框架，你也需要先学习JDBC作为这些的基础。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>对于JDBC的具体怎么实现，这个真不需要了解到那么深入。我推荐大家学习JDBC至少需要掌握以下内容：&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>1.JDBC的原理: JDBC为接口，可以有不同的驱动driver类&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>2.JDBC中的一些基本概念: connection， statement， resultset 等&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>3.JDBC使用的基本流程&lt;/p>&lt;p>&lt;br>&lt;/p></description></item><item><title>Java总结篇系列：Java泛型</title><link>https://pangyd.com/post/128-java-java/</link><pubDate>Sun, 08 Oct 2017 20:14:45 +0800</pubDate><guid>https://pangyd.com/post/128-java-java/</guid><description>&lt;p>首先，我们看下下面这段简短的代码:&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>public class GenericTest { &amp;nbsp; &amp;nbsp;public static void main(String[] args) {&lt;/p>&lt;p>&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; List list = new ArrayList();&lt;/p>&lt;p>&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; list.add("qqyumidi");&lt;/p>&lt;p>&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; list.add("corn");&lt;/p>&lt;p>&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; list.add(100); &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;for (int i = 0; i &amp;lt; list.size(); i++) {&lt;/p>&lt;p>&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; String name = (String) list.get(i); // 1&lt;/p>&lt;p>&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; System.out.println("name:" + name);&lt;/p>&lt;p>&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p></description></item><item><title>删雇主网站源码判刑五年！！</title><link>https://pangyd.com/post/127/</link><pubDate>Sat, 07 Oct 2017 19:13:56 +0800</pubDate><guid>https://pangyd.com/post/127/</guid><description>&lt;p>据新华社报道，软件工程师徐某离职后因公司未能如期结清工资，便利用其在所设计的网站中安插的后门文件将网站源代码全部删除。&lt;/p>&lt;p>公诉机关北京市丰台区人民检察机关指控，2016 年 4 月 27 日 9 时许，徐某利用其预先设置在北京某眼镜公司购物网站中的后门文件，对该网站的源代码执行删除操作，造成该网站无法正常运行。经鉴定，造成直接经济损失 26．5 万元。&lt;/p>&lt;p>庭审现场，徐某当庭认罪并向被害单位道歉。经调解，其家属代为赔偿被害单位经济损失 5 万元，并已实际履行。公司法定代表人张某代表公司对徐某表示谅解，并请求法院对徐某从轻处罚。记者 20 日从北京市丰台区人民法院获悉，最终徐某破坏计算机信息系统罪成立，获刑五年。&lt;/p>&lt;p>&lt;img src="https://pangyd.com/uploads/2017/10/7fa219b8a2dd5efb.jpg" alt="76e2070be9db2669.jpg">&lt;br>&lt;/p>&lt;p>@浮生若梦：不给清工资这事就这么算了？&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>@TTapple：都谅解了，还判五年&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>@码哥：不给人结工资，为什么自己的劳动成果不能删？&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>@永远的雨林：维护自己权益的手段有些极端&lt;/p>&lt;p>￼&lt;/p>&lt;p>来自：程序员头条&lt;/p></description></item><item><title>Java面试常被问到的题目+解答</title><link>https://pangyd.com/post/125-java/</link><pubDate>Thu, 05 Oct 2017 21:24:02 +0800</pubDate><guid>https://pangyd.com/post/125-java/</guid><description>&lt;p class="">&lt;span>摘要：&lt;/span>&amp;nbsp;第一，anonymousinnerclass(匿名内部类)是否可以extends(继承)其它类，是否可以implements(实现)interface(接口)? 不行,对于匿名内部类,看到的一句话说的很到位: new &amp;lt;类或接口&amp;gt; &amp;lt;类的主体&amp;gt; 这种形式的new语句声明一个新的匿名类，他对一个给定的类进行扩展，或实现一个给定的接口。&lt;/p>&lt;p>&lt;span>&lt;span>&lt;span>第一，anonymousinnerclass(匿名内部类)是否可以extends(继承)其它类，是否可以implements(实现)interface(接口)?&lt;/span>&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>&lt;br>&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>不行,对于匿名内部类,看到的一句话说的很到位:&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>&lt;br>&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>new &amp;lt;类或接口&amp;gt; &amp;lt;类的主体&amp;gt;&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>这种形式的new语句声明一个新的匿名类，他对一个给定的类进行扩展，或实现一个给定的接口。他还创建那个类的一个新实例，并把他作为语句的结果而返回。&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>&lt;br>&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>这就是匿名类的实质,它本身就是一个类的继承或一个接口的实现,所以继承其它类或借口是无意义的.在eclipse中冶证实了我的想法.无论是继承其它类还是实现其它借口都显示Syntax error on token。&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>&lt;br>&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>&lt;span>第二，staticnestedclass和innerclass的不同，说得越多越好(面试题有的很笼统)。&lt;/span>&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>&lt;br>&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>static nested class 指静态嵌套类,或称嵌套类,是C++中常用的说法,inner class指内部类,是JAVA中的说法。&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>&lt;br>&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>内部类是一个类内部类的统称,具体分为四种：成员类,静态成员类，局部类，匿名类。其中匿名类是局部类的特殊情况。对于成员类和静态成员类都存在于类的顶层代码中。相当于类的静态方法和非静态方法的关系。区别在于成员类依赖于类实例而静态成员类不依赖。所以前者只能访问实例方法和成员而后者只能访问静态方法和成员。它们都用于创建一个只和当前类有关。和其它类无关的依赖类.是否静态取决于是否依赖类的实例。局部类相当于局部变量。存在于类的局部代码中。相当于在main()中随意定义和使用类。唯一的不同是它只能使用final型的局部变量。这和垃圾回收机制有关。即局部变量会在代码块结束后被回收。而对象不一定。所以对象只能使用final的局部变量。同样，局部类存在的局部代码块也可以有静态和非静态的差别。局部类罪常见的应用就是匿名类。匿名类就是无名子的局部类。常在SWING设计中的添加监听中出现。&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>&lt;br>&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>static nested class相当于inner class中的静态成员类。&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>&lt;span>第三，&amp;amp;和&amp;amp;&amp;amp;的区别。&lt;/span>&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>&lt;br>&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>这个问得很少。&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>&lt;br>&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>&amp;amp;和^,&amp;lt;&amp;lt;,&amp;lt;&amp;lt;&amp;lt;,|同属于位运算符,其中&amp;amp;是按位与,例如,1&amp;amp;1=1，1&amp;amp;0=0，&amp;amp;&amp;amp;是逻辑运算符,处理真假值，例如,true&amp;amp;&amp;amp;true=true。&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>如果你想学习Java可以来这个群，首先是二二零，中间是142，最后是906，里面可以学习和交流，也有资料可以下载。&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>&lt;br>&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>&lt;span>第四，hashmap和hashtable的区别。&lt;/span>&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>&lt;br>&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>常问。&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>&lt;br>&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>hashmap可以看做是hashtable的替代者，HashMap的Value和Key都可为NULL，而HashTable不可以，同时，HashTable是线程同步的，而HashMap不是.HashTable用Iterator遍历，HashMap用Enumeration遍历。HashTable中hash数组默认大小是11，增加的方式是 old*2+1。HashMap中hash数组的默认大小是16，而且一定是2的指数。计算index的方法不同，HashTable直接利用hashcode()得出，HashMap对hashcode重新计算得出。&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>&lt;span>第五，collection和collections的区别。&lt;/span>&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>&lt;br>&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>你千万别说一个是单数一个是复数。&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>&lt;br>&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>collection是结合类的上级接口，子接口有List和Set等，Collections是java.util下的一个工具类，提供一些列静态方法对集合搜索排序线程同步化等。&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>&lt;br>&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>&lt;span>第六，什么时候用assert。&lt;/span>&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>&lt;br>&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>api级的技术人员有可能会问这个。&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>&lt;br>&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>在调试和优化中使用，用于判断逻辑表达式真假,若为假，终止程序并返回异常.assert比if的优点在于可以选择是否开启assert检查，也就是说assert产生的测试代码可以在正式发布时候选择忽略，这带来极大便利，默认assert检查是关闭的。此外，Junit相比assert来说，有着相似但更强大的测试能力。&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>&lt;br>&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>&lt;span>第七，gc是什么?为什么要有gc?&lt;/span>&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>&lt;br>&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>基础。&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>&lt;br>&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>GC 即 garbage collection(垃圾收集)，是JAVA用于回收内存的一种方式，主要的实现方法有引用计数，标记回收，复制清除等，GC可以避免内存泄露和堆栈溢出，有效提高内存的利用效率，同时将程序员从繁琐的内存管理中释放出来。&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>&lt;br>&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>&lt;span>第八，string s=new string("xyz");创建了几个stringobject?&lt;/span>&lt;/span>&lt;/span>&lt;/p></description></item><item><title>10种编程语言写Hello World，你会几个？</title><link>https://pangyd.com/post/124-10hello-world/</link><pubDate>Wed, 04 Oct 2017 19:58:19 +0800</pubDate><guid>https://pangyd.com/post/124-10hello-world/</guid><description>&lt;p>Hello World是我们进入编程的第一句运行的语言了，至少对于我是这样的，今天小编我收集了19种&lt;a href="https://pangyd.com/" target="_blank">编程语言&lt;/a>写的&lt;a href="https://pangyd.com/" target="_blank">Hello World&lt;/a>,你能看懂几个？&lt;/p>&lt;p>&lt;span id="article-img-0" class="a-image">&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/span>&lt;/p>&lt;p>1、C&lt;/p>&lt;p>&lt;span id="article-img-1" class="a-image">&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/span>&lt;/p>&lt;p>2、&lt;a href="https://www.yidianzixun.com/channel/w/java" target="_blank">Java&lt;/a>&lt;/p>&lt;p>&lt;span id="article-img-2" class="a-image">&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/span>&lt;/p>&lt;p>3、C++&lt;/p>&lt;p>&lt;span id="article-img-3" class="a-image">&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/span>&lt;/p>&lt;p>4、&lt;a href="https://www.yidianzixun.com/channel/w/php" target="_blank">PHP&lt;/a>&lt;/p>&lt;p>&lt;span id="article-img-4" class="a-image">&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/span>&lt;/p>&lt;p>5、Basic&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>6、C#&lt;/p>&lt;p>&lt;span id="article-img-5" class="a-image">&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/span>&lt;/p>&lt;p>7、&lt;a href="https://www.yidianzixun.com/channel/w/python" target="_blank">Python&lt;/a>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>8、&lt;a href="https://www.yidianzixun.com/channel/w/objective-c" target="_blank">Objective-C&lt;/a>&lt;/p>&lt;p>&lt;span id="article-img-6" class="a-image">&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/span>&lt;/p>&lt;p>9、&lt;a href="https://www.yidianzixun.com/channel/w/javascript" target="_blank">JavaScript&lt;/a>&lt;/p>&lt;p>&lt;span id="article-img-7" class="a-image">&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/span>&lt;/p>&lt;p>10、汇编语言 x86&lt;/p>&lt;p>&lt;span id="article-img-8" class="a-image">&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/span>&lt;/p>&lt;p>&lt;span id="article-img-9" class="a-image">&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/span>&lt;/p>&lt;p>&lt;span id="article-img-10" class="a-image">&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/span>&lt;/p>&lt;p>&lt;ol class=" list-paddingleft-2" style="text-align: justify">&lt;/ol>&lt;/p>&lt;p style="text-align: start">当然，编程语言远不止于此，大家学习的一定要记得脚踏实地，不要想着速成，&lt;a target="_self" href="https://pangyd.com/">编程&lt;/a>行业没有速成，只有代码量，希望大家能够铭记这一点，不要走错路。你最喜欢哪门编程语言呢，留言说说你的想法吧，最后我说一句：C语言是世界上最好的语言。&lt;/p></description></item><item><title>一张图读懂程序员们的心酸</title><link>https://pangyd.com/post/123/</link><pubDate>Wed, 04 Oct 2017 19:55:38 +0800</pubDate><guid>https://pangyd.com/post/123/</guid><description>&lt;img src="https://pangyd.com/uploads/2017/10/64ba89bfccdfe979.jpg" alt="mmexport1507118095586.jpg"></description></item><item><title>Java 中的异常和处理详解</title><link>https://pangyd.com/post/122-java/</link><pubDate>Tue, 03 Oct 2017 19:16:17 +0800</pubDate><guid>https://pangyd.com/post/122-java/</guid><description>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;strong>&lt;span>简介&lt;/span>&lt;/strong>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>程序运行时，发生的不被期望的事件，它阻止了程序按照程序员的预期正常执行，这就是异常。异常发生时，是任程序自生自灭，立刻退出终止，还是输出错误给用户？或者用C语言风格：用函数返回值作为执行状态？。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>Java提供了更加优秀的解决办法：异常处理机制。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>异常处理机制能让程序在异常发生时，按照代码的预先设定的异常处理逻辑，针对性地处理异常，让程序尽最大可能恢复正常并继续执行，且保持代码的清晰。&lt;/p>&lt;p>Java中的异常可以是函数中的语句执行时引发的，也可以是程序员通过throw 语句手动抛出的，只要在Java程序中产生了异常，就会用一个对应类型的异常对象来封装异常，JRE就会试图寻找异常处理程序来处理异常。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>Throwable类是Java异常类型的顶层父类，一个对象只有是 Throwable 类的（直接或者间接）实例，他才是一个异常对象，才能被异常处理机制识别。JDK中内建了一些常用的异常类，我们也可以自定义异常。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;strong>&lt;span>Java异常的分类和类结构图&lt;/span>&lt;/strong>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>Java标准裤内建了一些通用的异常，这些类以Throwable为顶层父类。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>Throwable又派生出Error类和Exception类。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>错误：Error类以及他的子类的实例，代表了JVM本身的错误。错误不能被程序员通过代码处理，Error很少出现。因此，程序员应该关注Exception为父类的分支下的各种异常类。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>异常：Exception以及他的子类，代表程序运行时发送的各种不期望发生的事件。可以被Java异常处理机制使用，是异常处理的核心。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p style="text-align: center">&lt;img class="" title="858860-20170911125844719-1230755033" data-src="https://pangyd.com/uploads/2017/10/74c10f869f038762.png" data-ratio="0.637883008356546" data-w="718" data-type="png" src="https://pangyd.com/uploads/2017/10/74c10f869f038762.png" data-fail="0">&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>总体上我们根据Javac对异常的处理要求，将异常类分为2类。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>非检查异常（unckecked exception）：Error 和 RuntimeException 以及他们的子类。javac在编译时，不会提示和发现这样的异常，不要求在程序处理这些异常。所以如果愿意，我们可以编写代码处理（使用try…catch…finally）这样的异常，也可以不处理。对于这些异常，我们应该修正代码，而不是去通过异常处理器处理 。这样的异常发生的原因多半是代码写的有问题。如除0错误ArithmeticException，错误的强制类型转换错误ClassCastException，数组索引越界ArrayIndexOutOfBoundsException，使用了空对象NullPointerException等等。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>检查异常（checked exception）：除了Error 和 RuntimeException的其它异常。javac强制要求程序员为这样的异常做预备处理工作（使用try…catch…finally或者throws）。在方法中要么用try-catch语句捕获它并处理，要么用throws子句声明抛出它，否则编译不会通过。这样的异常一般是由程序的运行环境导致的。因为程序可能被运行在各种未知的环境下，而程序员无法干预用户如何使用他编写的程序，于是程序员就应该为这样的异常时刻准备着。如SQLException , IOException,ClassNotFoundException 等。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>需要明确的是：检查和非检查是对于javac来说的，这样就很好理解和区分了。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;strong>&lt;span>初识异常&lt;/span>&lt;/strong>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>下面的代码会演示2个异常类型：ArithmeticException 和 InputMismatchException。前者由于整数除0引发，后者是输入的数据不能被转换为int类型引发。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;blockquote>&lt;p>&lt;span>package com.example;&lt;/span>&lt;/p>&lt;p>&lt;span>import java. util .Scanner ;&lt;/span>&lt;/p>&lt;p>&lt;span>public class AllDemo&lt;/span>&lt;/p>&lt;p>&lt;span>{&lt;/span>&lt;/p>&lt;p>&lt;span>&amp;nbsp; &amp;nbsp; &amp;nbsp; public static void main (String [] args )&lt;/span>&lt;/p></description></item><item><title>Java序列化的几种方式以及序列化的作用</title><link>https://pangyd.com/post/121-java/</link><pubDate>Mon, 02 Oct 2017 20:40:10 +0800</pubDate><guid>https://pangyd.com/post/121-java/</guid><description>&lt;h1 style="text-align: justify">一.Java序列化的作用&lt;/h1>&lt;p style="text-align: justify">有的时候我们想要把一个Java对象变成字节流的形式传出去，有的时候我们想要从一个字节流中恢复一个Java对象。例如，有的时候我们想要&lt;/p>&lt;p style="text-align: justify">把一个Java对象写入到硬盘或者传输到网路上面的其它计算机，这时我们就需要自己去通过java把相应的对象写成转换成字节流。对于这种通用&lt;/p>&lt;p style="text-align: justify">的操作，我们为什么不使用统一的格式呢？没错，这里就出现了java的序列化的概念。在Java的OutputStream类下面的子类ObjectOutput-&lt;/p>&lt;p style="text-align: justify">Stream类就有对应的WriteObject(Object object) 其中要求对应的object实现了java的序列化的接口。&lt;/p>&lt;p style="text-align: justify">为了更好的理解java序列化的应用，我举两个自己在开发项目中遇到的例子:&lt;/p>&lt;p style="text-align: justify">1)在使用tomcat开发JavaEE相关项目的时候，我们关闭tomcat后，相应的session中的对象就存储在了硬盘上，如果我们想要在tomcat重启的&lt;/p>&lt;p style="text-align: justify">时候能够从tomcat上面读取对应session中的内容，那么保存在session中的内容就必须实现相关的序列化操作。&lt;/p>&lt;p style="text-align: justify">2)如果我们使用的java对象要在分布式中使用或者在rmi远程调用的网络中使用的话，那么相关的对象必须实现java序列化接口。&lt;/p>&lt;p style="text-align: justify">亲爱的小伙伴，大概你已经了解了java序列化相关的作用，接下来们来看看如何实现java的序列化吧。~&lt;/p>&lt;h1 style="text-align: justify">二.实现java对象的序列化和反序列化。&lt;/h1>&lt;p style="text-align: justify">Java对象的序列化有两种方式。&lt;/p>&lt;p style="text-align: justify">a.是相应的对象实现了序列化接口Serializable，这个使用的比较多，对于序列化接口Serializable接口是一个空的接口，它的主要作用就是&lt;/p>&lt;p style="text-align: justify">标识这个对象时可序列化的，jre对象在传输对象的时候会进行相关的封装。这里就不做过多的介绍了。&lt;/p>&lt;p style="text-align: justify">下面是一个实现序列化接口的Java序列化的例子:非常简单&lt;/p>&lt;pre class="">&lt;code class="">&lt;span class="">package&lt;/span> com.shop.domain;&lt;span class="">import&lt;/span> java.util.Date;&lt;span class="">public&lt;/span> &lt;span class="">&lt;span class="">class&lt;/span> &lt;span class="">Article&lt;/span> &lt;span class="">implements&lt;/span> &lt;span class="">java&lt;/span>.&lt;span class="">io&lt;/span>.&lt;span class="">Serializable&lt;/span> {&lt;/span> &amp;nbsp; &amp;nbsp;&lt;span class="">private&lt;/span> &lt;span class="">static&lt;/span> &lt;span class="">final&lt;/span> &lt;span class="">long&lt;/span> serialVersionUID = &lt;span class="">1&lt;/span>L; &amp;nbsp; &amp;nbsp;&lt;span class="">private&lt;/span> Integer id; &amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span class="">private&lt;/span> String title; &amp;nbsp;&lt;span class="">//文章标题&lt;/span> &amp;nbsp; &amp;nbsp;&lt;span class="">private&lt;/span> String content; &amp;nbsp;&lt;span class="">// 文章内容&lt;/span> &amp;nbsp; &amp;nbsp;&lt;span class="">private&lt;/span> String faceIcon;&lt;span class="">//表情图标&lt;/span> &amp;nbsp; &amp;nbsp;&lt;span class="">private&lt;/span> Date postTime; &lt;span class="">//文章发表的时间&lt;/span> &amp;nbsp; &amp;nbsp;&lt;span class="">private&lt;/span> String ipAddr; &amp;nbsp;&lt;span class="">//用户的ip&lt;/span> &amp;nbsp; &amp;nbsp;&lt;span class="">private&lt;/span> User author; &amp;nbsp;&lt;span class="">//回复的用户&lt;/span> &amp;nbsp; &amp;nbsp;&lt;span class="">public&lt;/span> Integer &lt;span class="">getId&lt;/span>() { &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class="">return&lt;/span> id; &amp;nbsp; &amp;nbsp;} &amp;nbsp; &amp;nbsp;&lt;span class="">public&lt;/span> &lt;span class="">void&lt;/span> &lt;span class="">setId&lt;/span>(Integer id) { &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class="">this&lt;/span>.id = id; &amp;nbsp; &amp;nbsp;} &amp;nbsp; &amp;nbsp;&lt;span class="">public&lt;/span> String &lt;span class="">getTitle&lt;/span>() { &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class="">return&lt;/span> title; &amp;nbsp; &amp;nbsp;} &amp;nbsp; &amp;nbsp;&lt;span class="">public&lt;/span> &lt;span class="">void&lt;/span> &lt;span class="">setTitle&lt;/span>(String title) { &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class="">this&lt;/span>.title = title; &amp;nbsp; &amp;nbsp;} &amp;nbsp; &amp;nbsp;&lt;span class="">public&lt;/span> String &lt;span class="">getContent&lt;/span>() { &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class="">return&lt;/span> content; &amp;nbsp; &amp;nbsp;} &amp;nbsp; &amp;nbsp;&lt;span class="">public&lt;/span> &lt;span class="">void&lt;/span> &lt;span class="">setContent&lt;/span>(String content) { &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class="">this&lt;/span>.content = content; &amp;nbsp; &amp;nbsp;} &amp;nbsp; &amp;nbsp;&lt;span class="">public&lt;/span> String &lt;span class="">getFaceIcon&lt;/span>() { &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class="">return&lt;/span> faceIcon; &amp;nbsp; &amp;nbsp;} &amp;nbsp; &amp;nbsp;&lt;span class="">public&lt;/span> &lt;span class="">void&lt;/span> &lt;span class="">setFaceIcon&lt;/span>(String faceIcon) { &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class="">this&lt;/span>.faceIcon = faceIcon; &amp;nbsp; &amp;nbsp;} &amp;nbsp; &amp;nbsp;&lt;span class="">public&lt;/span> Date &lt;span class="">getPostTime&lt;/span>() { &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class="">return&lt;/span> postTime; &amp;nbsp; &amp;nbsp;} &amp;nbsp; &amp;nbsp;&lt;span class="">public&lt;/span> &lt;span class="">void&lt;/span> &lt;span class="">setPostTime&lt;/span>(Date postTime) { &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class="">this&lt;/span>.postTime = postTime; &amp;nbsp; &amp;nbsp;} &amp;nbsp; &amp;nbsp;&lt;span class="">public&lt;/span> User &lt;span class="">getAuthor&lt;/span>() { &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class="">return&lt;/span> author; &amp;nbsp; &amp;nbsp;} &amp;nbsp; &amp;nbsp;&lt;span class="">public&lt;/span> &lt;span class="">void&lt;/span> &lt;span class="">setAuthor&lt;/span>(User author) { &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class="">this&lt;/span>.author = author; &amp;nbsp; &amp;nbsp;} &amp;nbsp; &amp;nbsp;&lt;span class="">public&lt;/span> String &lt;span class="">getIpAddr&lt;/span>() { &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class="">return&lt;/span> ipAddr; &amp;nbsp; &amp;nbsp;} &amp;nbsp; &amp;nbsp;&lt;span class="">public&lt;/span> &lt;span class="">void&lt;/span> &lt;span class="">setIpAddr&lt;/span>(String ipAddr) { &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class="">this&lt;/span>.ipAddr = ipAddr; &amp;nbsp; &amp;nbsp;}}&lt;/code>&lt;/pre>&lt;p style="text-align: justify">b.实现序列化的第二种方式为实现接口Externalizable，Externlizable的部分源代码如下:&lt;/p></description></item><item><title>国庆你们加班吗？程序员：看天意</title><link>https://pangyd.com/post/120/</link><pubDate>Sun, 01 Oct 2017 20:32:49 +0800</pubDate><guid>https://pangyd.com/post/120/</guid><description>&lt;p>最近流行这么一张图&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>你的专业vs别人眼中的你的专业&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>没有女程序员吗？&lt;/p>&lt;p>&lt;span>有！不过可能是这样的&lt;/span>&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>为什么都说程序员不是在加班，就是在加班的路上？&lt;/p>&lt;p>&lt;span>因为&lt;/span>&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>额，这么剑拔弩张吗？&lt;/p>&lt;p>&lt;span>对&lt;/span>&lt;/p>&lt;p>这是为什么呢&lt;/p>&lt;p>&lt;span>因为&lt;/span>&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>那...那你为什么要做程序员呢？钱多吗？&lt;/p>&lt;p>&lt;span>你觉得多吗？&lt;/span>&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>你为什么还选择在这里做名程序员呢？&lt;/p>&lt;p>&lt;span>我们坚定信念，致力成为未来互联网 领域里的连接器。&lt;/span>&lt;/p>&lt;p>最后问一句，国庆你们加班吗？&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>&lt;span>看天意&lt;/span>&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p>&lt;p>&lt;span>请关爱我们的程序员因为他们...&lt;/span>&lt;/p>&lt;p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E">&lt;/p></description></item><item><title>程序员编程生涯中常会犯的7个错误</title><link>https://pangyd.com/post/119-7/</link><pubDate>Sat, 30 Sep 2017 19:16:43 +0800</pubDate><guid>https://pangyd.com/post/119-7/</guid><description>&lt;p>&lt;span>时间久了，我发现很多程序员总是犯着相同的错误，前仆后继，却毫不自知。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>下面就是程序员在他们的软件开发生涯中最常犯的7个错误。&lt;/span>&lt;/p>&lt;h2>&lt;strong>&lt;span>&lt;br>&lt;/span>&lt;/strong>&lt;/h2>&lt;h2>&lt;strong>&lt;span>▼没有明确的目标&lt;/span>&lt;/strong>&lt;span>&lt;br>&lt;/span>&lt;/h2>&lt;p>&lt;strong>&lt;span>&lt;br>&lt;/span>&lt;/strong>&lt;/p>&lt;p>&lt;span>心中没有终点目标，那就只会随波逐流。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>如果你想在软件开发的职业生涯上获得成功，那么你需要有一个明确的目标。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>仅仅只是对遥远的未来有一个模糊的想法是不够的。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>相反，你应该有坚实的目标——在某个时间段内的首要目的——明确定义的目标。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>我认识许多程序员和所谓的专业人士庸庸碌碌地在同一个岗位上干了几十年，是的，你没听错，就是几十年！&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>这是一场悲剧，但如果没有目标，这就是你人生的默认选择。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>请引以为戒，否则下一个悲剧就会是你。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>那么，我们能做些什么呢？&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>从今天开始，从现在开始，花一些时间，好好想想你的编程生涯，并决定自己的近期目标。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>我的意思是，明确&lt;span>当前的首要目标&lt;/span>。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>一旦达到这个目标之后，再制定一个新的目标，但是现在，请好好想想，你的编程生涯需要实现什么目的？&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;h2>&lt;span>你可以记下来，放到每天都能看到的位置，来提醒自己不断地朝着目标前进。&lt;/span>&lt;/h2>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;h2>&lt;strong>&lt;span>▼不投资于非技术和“软技能”&lt;/span>&lt;/strong>&lt;/h2>&lt;p>&lt;strong>&lt;span>&lt;br>&lt;/span>&lt;/strong>&lt;/p>&lt;p>&lt;span>我认识很多程序员其实真的很擅长于写代码。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>我也认识很多程序员在算法上确实远远优于我。他们理解和思考复杂架构的水平，是我所望尘莫及的。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>但你猜怎么着？&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>在我的软件开发职业生涯中，我超越了他们，不仅包括职位职务，还有工资，工作效率，性能等等。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>我说出来不是为了炫耀，只是想要说明软技能对我们的编程生涯有多重要，而不仅仅是那些大多数程序员重点关注的技术技能。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>作为一个软件开发人员，你肯定知道，你的工作并不仅仅是编写代码。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>还有其他许多必要的重点技能。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>我们得时常与人打交道，所以人际交往能力是必须的。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>紧张的时间期限，快速的变化则需要稳定的心理，能够全神贯注，并懂得自我激励。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>在一个不断变化的环境中，在一个充斥了各种繁多和意外的环境中，我们要学会如何优先安排，并尽可能地富有成效。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>此外我们也不能忽略健康以及经济因素，如果忽略它们的话也同样会导致失败甚至是毁灭。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>相关方面的内容还有很多，我就不一一赘述了，感兴趣的话，可以阅读《Soft Skills: The Software Developer’s Manual》 做深入的了解。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>总而言之，不管你做的是哪方面的工作，软技能几乎总是比硬技能、技术技能更重要——所以一定要好好学习这方面的知识。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;/p>&lt;h2>&lt;strong>&lt;span>▼不参与社区&lt;/span>&lt;/strong>&lt;/h2>&lt;p>&lt;strong>&lt;span>&lt;br>&lt;/span>&lt;/strong>&lt;/p>&lt;p>&lt;span>我做的其中一件让我的编程生涯受益无穷的事就是，参与社区。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>这不但让我有了归属感，不再感觉孤单，还能帮助我提高技能，敢于设定更高的目标。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>所以，我强烈建议你加入到编程社区中。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>众人拾柴火焰高，参与社区，是一种积极的成长方式。&lt;/span>&lt;/p></description></item><item><title>Java 和 JavaScript 的关系！</title><link>https://pangyd.com/post/118-java-javascript/</link><pubDate>Fri, 29 Sep 2017 20:28:20 +0800</pubDate><guid>https://pangyd.com/post/118-java-javascript/</guid><description>&lt;p>&lt;br>&lt;/p>&lt;p style="text-align: center">&lt;span>58的姚总曾出现这么个尴尬事&lt;/span>&lt;br>&lt;/p>&lt;p style="text-align: center">&lt;br>&lt;/p>&lt;p style="text-align: center">&lt;img data-s="300,640" data-type="jpeg" data-src="https://pangyd.com/uploads/2017/09/74c10f869f038762.jpg" class="" data-ratio="2.2" data-w="440" src="https://pangyd.com/uploads/2017/09/74c10f869f038762.jpg" data-fail="0">&lt;/p>&lt;p style="text-align: center">&lt;br>&lt;/p>&lt;p style="text-align: center">&lt;span>强行装逼失败&lt;img data-src="https://pangyd.com/uploads/2017/09/1d9ea9ee6040df52.png" data-ratio="1" data-w="20" _width="20px" src="https://pangyd.com/uploads/2017/09/1d9ea9ee6040df52.png" class="" data-fail="0">&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;span>&amp;nbsp;这 JavaScript 和 Java 有啥区别&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;span>据说还有很多人不知道&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;span>于是，猿妹找了一堆形象生动的解答&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;span>来给大家科普一下两者区别！！&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;span>答案有这样的&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;span>↓↓↓&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;img data-s="300,640" data-type="jpeg" data-src="https://pangyd.com/uploads/2017/09/74c10f869f038762.jpg" class="" data-ratio="0.8317152103559871" data-w="309" src="https://pangyd.com/uploads/2017/09/74c10f869f038762.jpg" data-fail="0">&lt;/p>&lt;p style="text-align: center">&lt;span>这样的&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;span>↓↓↓&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;img data-s="300,640" data-type="jpeg" data-src="https://pangyd.com/uploads/2017/09/74c10f869f038762.jpg" class="" data-ratio="0.4451754385964912" data-w="912" src="https://pangyd.com/uploads/2017/09/74c10f869f038762.jpg" data-fail="0">&lt;/p>&lt;p style="text-align: center">&lt;img data-s="300,640" data-type="jpeg" data-src="https://pangyd.com/uploads/2017/09/74c10f869f038762.jpg" class="" data-ratio="0.62" data-w="600" src="https://pangyd.com/uploads/2017/09/74c10f869f038762.jpg" data-fail="0">&lt;/p>&lt;p style="text-align: center">&lt;br>&lt;/p>&lt;p style="text-align: center">最形象当属这样的&lt;/p></description></item><item><title>为什么Java程序员薪资一直居高不下？</title><link>https://pangyd.com/post/117-java/</link><pubDate>Thu, 28 Sep 2017 21:05:35 +0800</pubDate><guid>https://pangyd.com/post/117-java/</guid><description>&lt;p>众所周知，目前互联网行业是众多行业中薪资待遇最好的，包括程序员、运营、新媒体和这个行业周边的商务、销售等人员的工资，都是其他行业所不能比拟的。本文就为大家分析一下Java程序员薪资居高不下的原因。&lt;div>&lt;br>&lt;/div>&lt;div>程序员问科比：你为什么这么成功?&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>科比：你知道洛杉矶凌晨4点的样子吗?&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>程序员：不知道，不过我知道凌晨4点的北京，一般那时候我还没睡，怎么了?&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>科比：没，没什么&amp;hellip;&amp;hellip;&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>上面的段子说明了程序员加班的程度，有的人看到这一点就明了了。但这不是唯一的原因。&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>曾经看过一个等式：热门+门槛高=高工资，那么我们就从门槛开始分析原因。&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>1. Java程序员的门槛相对比较高&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>首先要计算机技术或是相关专业的大学生，原因有二，一是，Java对从业人员素质有一点要求，计算机相关行业会了解最基本的互联网的相关知识，以及简单的语言基础；二是，从事这一行业，招聘公司对学历有要求，最起码要是专科以上的。&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>当然，也不排除有非计算机专业的从事Java行业的人，但是万事开头难，很多人抱着很大的希望去学习，随着遇到的困难越来越多，慢慢的也就放弃了，因此有一部分人都倒在了入门的路上。所以干这一行的人相对其他行业还是少。&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>2. Java行业市场需求存在巨大的缺口&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>这几年中国在移动互联网这块发展非常迅猛，各种创业公司、小团队如雨后春笋般冒出来，对Java开发的需要变大。但存在人才发展跟不上市场的需求的现状，相对应的给优秀Java人才开出的薪资待遇随之水涨船高。&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>3. 程序员的确很辛苦，需要不断学习、进步&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>辛苦分劳力和脑力两种，劳力工作不难，每天重复着体力活；但脑力活就不一样了，程序员一辈子都在学习、在挑战，因为这是一个不进步就out的行业。&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>随着互联网的发展，很多企业随着业务发展要求服务器程序更稳定，更可靠。如：京东，淘宝等大型人网站均采用Java框架进行开发。银行券商等机构均采用Java作为开发语言。&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>对于在职的Java从业人员来讲，不断的努力吸收新的知识，跟上互联网进步的节奏是很重要的。&lt;/div>&lt;/p></description></item><item><title>开发人员需要掌握的英文词汇，必须要学会的</title><link>https://pangyd.com/post/116/</link><pubDate>Wed, 27 Sep 2017 11:59:42 +0800</pubDate><guid>https://pangyd.com/post/116/</guid><description>&lt;p>当年学习Java时想过，英语不好或者一窍不通，能不能学好Java开发；就这个问题请教了开发前辈，答案是不懂英文也可以学好Java，但必须要学会一些常用英文词汇，必竟Java是英文开发创造的，以下整理了开发中常用的词汇及中文含义；当然知道这些远远不够，我们可以在学习工作过程中慢慢积累，渐渐会发现原来学会了这么多英文，好了，开始学习吧&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>我以英文首字母进行排序：&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>1、Abstract class 抽象类:抽象类是不允许实例化的类，因此一般它需要被进行扩展继承。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>2、Abstract method 抽象方法:抽象方法即不包含任何功能代码的方法。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>3、Anonymous class 匿名类:当你需要创建和使用一个类，而又不需要给出它的名字或者再次使用的使用，就可以利用匿&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>名类。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>4、Anonymous inner classes 匿名内部类:匿名内部类是没有类名的局部内部类。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>5、API 应用程序接口:提供特定功能的一组相关的类和方法的集合。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>6、Array 数组:存储一个或者多个相同数据类型的数据结构，使用下标来访问。在Java中作为对象处理。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>7、Base class 基类:即被扩展继承的类。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>8、Call stack 调用堆栈:调用堆栈是一个方法列表，按调用顺序保存所有在运行期被调用的方法。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>9、Casting 类型转换 :即一个类型到另一个类型的转换，可以是基本数据类型的转换，也可以是对象类型的转换。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>10、Char 字符:容纳单字符的一种基本数据类型。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>11、Child class 子类:见继承类Derived class&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>12、Class 类:面向对象中的最基本、最重要的定义类型。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>13、Class members 类成员:定义在类一级的变量，包括实例变量和静态变量。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>14、Class methods 类方法:类方法通常是指的静态方法，即不需要实例化类就可以直接访问使用的方法。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>15、Class variable 类变量:见静态变量Static variable&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>16、Collection 容器类:容器类可以看作是一种可以储存其他对象的对象，常见的容器类有Hashtables和Vectors。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>17、Collection interface 容器类接口:容器类接口定义了一个对所有容器类的公共接口。&lt;/p></description></item><item><title>java邮件类---MailUtils 用户网站统一发送激活码</title><link>https://pangyd.com/post/115-java-mailutils/</link><pubDate>Mon, 25 Sep 2017 20:52:08 +0800</pubDate><guid>https://pangyd.com/post/115-java-mailutils/</guid><description>&lt;pre lay-lang="Java" class="layui-code" skin="notepad">package cn.pyd.itcaststore.utils;

import java.net.Authenticator;
import java.net.PasswordAuthentication;
import java.util.Properties;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMessage.RecipientType;

public class MailUtils {
	public static void sendMail(String email,String emailMsg) throws AddressException,MessagingException{
		//1.创建Properties对象，并设置邮件服务器的基本信息
		Properties props=new Properties();
		//1.1设计邮件传输协议为SMIP
		 props.put("mail.smtp.host", "smtp.163.com");//存储发送邮件服务器的信息 
	 props.put("mail.smtp.auth", "true");//同时通过验证
	 props.setProperty("mail.transport.protocol", "smtp"); 
		//1.4创建验证器
		javax.mail.Authenticator auth=new javax.mail.Authenticator() {
			public javax.mail.PasswordAuthentication getPasswordAuthentication() {
				return new javax.mail.PasswordAuthentication("用户名", "密码");
			}
		};
		//实例化邮件会话Session
		Session session=Session.getInstance(props, auth);
		//2.创建一个Message，该对象相当于邮件内容
		Message message=new MimeMessage(session);
		//2.1设置发送者
		message.setFrom(new InternetAddress("用户名@163.com"));
		//2.2设置发送方式与接受者，邮件接受者在调用sendMail()方法时通过参数传递过来
		message.setRecipient(RecipientType.TO,new InternetAddress(email));
		//2.3设置邮件发送主题
		message.setSubject("用户激活");
		message.setContent(emailMsg, "text/html;charset=utf-8");
		//3.发送邮件
		Transport.send(message);
	}
}
&lt;/pre></description></item><item><title>学习Java需吃透这些基本概念你知道吗？</title><link>https://pangyd.com/post/114-java/</link><pubDate>Sun, 24 Sep 2017 21:14:30 +0800</pubDate><guid>https://pangyd.com/post/114-java/</guid><description>&lt;p>学习好比盖房子，打地基好很重要，房了能盖多高关键看地基；学习同样道理，基础知识是以后学习一切技术的必要条件，我们在准备学习一门开发语言时，首先要学习它的基础，不仅要会，更要融会贯通；万变不离其宗，无论技术框架怎么变，本质都是对基础的封装再造。&lt;div>&lt;br>&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>在以往的工作学习中，我总结了一些Java非常重要的知识点或者说基本概念，好了，进入正题：&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>1、面向对象编程（OOP）:OOP最重要的思想是类,类是模板,从类中构造一个对象,即创建了这个类的一个实例；&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>2、封装:是把数据和行为结合在一起，并对对象使用者隐藏数据的实现过程,通常一个对象中的数据叫他的实例字段(instance field) ；&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>3、继承:Java中允许在已经存在的类的基础上构建新的类,当你继承一个已经存在的类时,那么你就复用了这个类的方法和字段,同时你可以在新类中添加新的方法和字段；&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>4、多态:在java中,对象变量是多态的；需要注意的是java中不支持多重继承；&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>5、类之间的关系:&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>use-a :依赖关系 ；&lt;/div>&lt;div>has-a :聚合关系 ；&lt;/div>&lt;div>is-a : 继承关系&amp;ndash;例:A类继承了B类,此时A类不仅有了B类的方法,还有其自己的方法；&lt;/div>&lt;div>6、构造对象使用构造器:构造器是一种特殊的方法,它的作用是构造对象并对其初始化，&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>构造器特点:构造器可以有0个,一个或多个参数 ；&lt;/div>&lt;div>构造器和类名称是相同的；&lt;/div>&lt;div>一个类可以有多个构造器；&lt;/div>&lt;div>构造器没有返回值；&lt;/div>&lt;div>构造器一定是和new运算符一起使用的；&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>7、包(package)：Java允许把一个或多个类放在一起成为一组,称作为包,以便于更好的管理,标准Java库分为许多包如java.lang、java.util、java,net等,包是分层次的，所有的java包都在java和javax包层次内；&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>8、重载:当多个方法具有相同的名字而含有不同的参数时,这时就发生了重载，编译器会选出调用哪个方法；&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>9、健壮特性:Java采取了一个安全指针模型,能有效防止重写内存和数据崩溃；&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>10、安全:Java可以用来构建防病毒和防攻击的系统，事实证明Java在防毒方面做的比较好；&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>11、可移植性:Java中对基本数据结构类型的大小和算法都有严格的规定，所以有很好的可移植性；&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>12、多线程:由于Java的机制，它处理多线程的过程很简单,Java把多线程实现交给底下操作系统或线程程序完成，所以多线程是Java作为服务器端开发语言的流行原因之一；&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>13、动态绑定:这是Java调用对象方法的机制；&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>14、Java中的每一个类都是从Object类扩展而来的；&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>15、内部类:一个内部类的定义是定义在另一个内部类中；&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>以上只列出了比较重要的，必须掌握的知识点。&lt;/div>&lt;/p></description></item><item><title>书城注册登录servlet--UserService.java</title><link>https://pangyd.com/post/113-servlet-userservice-java/</link><pubDate>Sat, 23 Sep 2017 21:03:03 +0800</pubDate><guid>https://pangyd.com/post/113-servlet-userservice-java/</guid><description>&lt;pre lay-lang="Java" class="layui-code" skin="notepad">package cn.itcast.itcaststore.service;
import java.sql.SQLException;
import java.util.Date;
import javax.security.auth.login.LoginException;
import cn.itcast.itcaststore.dao.UserDao;
import cn.itcast.itcaststore.domain.User;
import cn.itcast.itcaststore.exception.ActiveUserException;
import cn.itcast.itcaststore.exception.RegisterException;
import cn.itcast.itcaststore.utils.MailUtils;

public class UserService {
	private UserDao dao = new UserDao();
	// 注册操作
	public void register(User user) throws RegisterException {
		// 调用dao完成注册操作
		try {
			dao.addUser(user);
			// 发送激活邮件
			String emailMsg = "感谢您注册网上书城，点击"
					+ "&lt;a href="http://localhost:8080/bookstore/activeUser?activeCode=&amp;quot;
					+ user.getActiveCode() + &amp;quot;">&amp;nbsp;激活&amp;nbsp;&lt;/a>后使用。"
							+ "&lt;br>为保障您的账户安全，请在24小时内完成激活操作";
			MailUtils.sendMail(user.getEmail(), emailMsg);
		} catch (Exception e) {
			e.printStackTrace();
			throw new RegisterException("注冊失败");
		}
	}
	// 激活用户
	public void activeUser(String activeCode) throws ActiveUserException {
		try {
			// 根据激活码查找用户
			User user = dao.findUserByActiveCode(activeCode);
			if (user == null) {
				throw new ActiveUserException("激活用户失败");
			}
			// 判断激活码是否过期 24小时内激活有效.
			// 1.得到注册时间
			Date registTime = user.getRegistTime();
			// 2.判断是否超时
			long time = System.currentTimeMillis() - registTime.getTime();
			if (time / 1000 / 60 / 60 &amp;gt; 24) {
				throw new ActiveUserException("激活码过期");
			}
			// 激活用户，就是修改用户的state状态
			dao.activeUser(activeCode);
		} catch (SQLException e) {
			e.printStackTrace();
			throw new ActiveUserException("激活用户失败");
		}
	}
	// 登录操作
	public User login(String username, String password) throws LoginException {
		try {
			//根据登录时表单输入的用户名和密码，查找用户
			User user = dao.findUserByUsernameAndPassword(username, password);
			//如果找到，还需要确定用户是否为激活用户
			if (user != null) {
				// 只有是激活才能登录成功，否则提示“用户未激活”
				if (user.getState() == 1) {
					return user;
				}
				throw new LoginException("用户未激活");
			}
			throw new LoginException("用户名或密码错误");
		} catch (SQLException e) {
			e.printStackTrace();
			throw new LoginException("登录失败");
		}
	}
}
&lt;/pre></description></item><item><title>啪啪啪！敲代码时你喜欢听什么音乐？下面这些歌单推荐给你</title><link>https://pangyd.com/post/112/</link><pubDate>Fri, 22 Sep 2017 20:38:02 +0800</pubDate><guid>https://pangyd.com/post/112/</guid><description>&lt;section class="">&lt;section class="">&lt;section class="">&lt;p>凌晨4点的北上广深，是他们最为熟悉的光景，啃着粗糙的盒饭，穿着格子衬衫，依然保持初恋般真。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>他们日日夜夜坚守在成功的背后，扮演默默无闻的幕后英雄。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>他们的名字是，IT人。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;/section>&lt;/section>&lt;/section>&lt;section class="">&lt;section class="">&lt;section class="">&lt;p>更多的时候，不光是电脑和键盘陪着我们度过一天，耳机和音乐也成了IT人生活中必不可少的一部分，上班和下班的路上，心情失落时，失眠时，甚至是工作时都可能会听音乐，让音乐为我们疗伤，让精神得以放松。甚至有&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;/section>&lt;/section>&lt;/section>&lt;section class="">&lt;section class="">&lt;section class="">&lt;p>20年写下1一亿行代码的阿里云神级程序猿为你推荐的歌单&amp;gt;&amp;gt;（https://bbs.aliyun.com/read/288999.html）&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;/section>&lt;/section>&lt;/section>&lt;section class="">&lt;section class="" style="text-align: center">&lt;img class="" data-src="https://pangyd.com/uploads/2017/09/74c10f869f038762.jpg" data-ratio="0.3583333" data-w="600" data-type="jpeg" src="https://pangyd.com/uploads/2017/09/74c10f869f038762.jpg" data-fail="0">&lt;/section>&lt;/section>&lt;section class="">&lt;section class="">&lt;section class="">&lt;p>&lt;br>&lt;/p>&lt;p>其实在工作时要尽量选择那些技能让我们深信愉悦，激发创造力和想象力但又不会使我们分心的音乐。有人说，适合这种情景的音乐有摇摆乐，爵士乐和蓝调音乐。还有轻音乐，比如班得瑞和神秘园的曲子，非常轻缓，沁人心脾。还有一种就是外文歌曲，歌词完全听不懂那种。甚至还有像这样的专门为程序员提供音乐的网站：&lt;/p>&lt;/section>&lt;/section>&lt;/section>&lt;section class="">&lt;section class="">&lt;section class="">&lt;p>&lt;br>&lt;/p>&lt;ul class="list-paddingleft-2">&lt;li>&lt;p>musicforprogramming.net/&lt;/p>&lt;/li>&lt;li>&lt;p>https://www.getworkdonemusic.com/&lt;/p>&lt;/li>&lt;/ul>&lt;p>&lt;br>&lt;/p>&lt;/section>&lt;/section>&lt;/section>&lt;section class="">&lt;section class="" style="text-align: center">&lt;img class="" data-src="https://pangyd.com/uploads/2017/09/74c10f869f038762.jpg" data-ratio="0.7857143" data-w="280" data-type="jpeg" src="https://pangyd.com/uploads/2017/09/74c10f869f038762.jpg" data-fail="0">&lt;/section>&lt;/section>&lt;section class="">&lt;section class="">&lt;section class="">&lt;p>&lt;br>&lt;/p>&lt;p>为了高效的工作要时刻的保持身心的预约，听歌是一个不错的选择，&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>比如：&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>T姐还在的时候，很多歌都不错，&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>例如&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>ghost love score&lt;/p>&lt;p>ever dream&lt;/p>&lt;p>nemo等等&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>后来&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>A姐来了有一些也不错，例如&lt;/p>&lt;p>bye bye beautiful等等&lt;/p>&lt;p>还有贝斯手marco唱的&lt;/p>&lt;p>while your lips are still red&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>等等，还有一些没词的曲子evanescence的也不错&lt;/p>&lt;p>产品改需求时就听powerwolf的&lt;/p>&lt;p>we drink your blood&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;/section>&lt;/section>&lt;/section>&lt;section class="">&lt;section class="" style="text-align: center">&lt;img class="" data-src="https://pangyd.com/uploads/2017/09/74c10f869f038762.jpg" data-ratio="1.11" data-w="400" data-type="jpeg" src="https://pangyd.com/uploads/2017/09/74c10f869f038762.jpg" data-fail="0">&lt;/section>&lt;/section>&lt;section class="">&lt;section class="">&lt;section class="">&lt;p>&lt;br>&lt;/p></description></item><item><title>Java验证码的绘制</title><link>https://pangyd.com/post/111-java/</link><pubDate>Fri, 22 Sep 2017 20:08:32 +0800</pubDate><guid>https://pangyd.com/post/111-java/</guid><description>&lt;pre lay-lang="Java" class="layui-code" skin="notepad">package cn.itcast.itcaststore.utils;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * 生成验证码的工具类
 */
public class CheckImageServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	// 集合中保存所有成语
	private List&lt;string> words = new ArrayList&lt;string>();
	@Override
	public void init() throws ServletException {
		// 初始化阶段，读取new_words.txt
		// web工程中读取文件，必须使用绝对磁盘路径
		String path = getServletContext().getRealPath("/WEB-INF/new_words.txt");
		try {
			BufferedReader reader = new BufferedReader(new InputStreamReader(
					new FileInputStream(path), "utf-8"));
			String line;
			while ((line = reader.readLine()) != null) {
				words.add(line);
			}
			reader.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 禁止缓存
		// response.setHeader("Cache-Control", "no-cache");
		// response.setHeader("Pragma", "no-cache");
		// response.setDateHeader("Expires", -1);
		int width = 180;
		int height = 30;
		// 步骤一 绘制一张内存中图片
		BufferedImage bufferedImage = new BufferedImage(width, height,
				BufferedImage.TYPE_INT_RGB);
		// 步骤二 图片绘制背景颜色 ---通过绘图对象
		Graphics graphics = bufferedImage.getGraphics();// 得到画图对象 --- 画笔
		// 绘制任何图形之前 都必须指定一个颜色
		graphics.setColor(getRandColor(200, 250));
		graphics.fillRect(0, 0, width, height);
		// 步骤三 绘制边框
		graphics.setColor(Color.WHITE);
		graphics.drawRect(0, 0, width - 1, height - 1);
		// 步骤四 四个随机数字
		Graphics2D graphics2d = (Graphics2D) graphics;
		// 设置输出字体
		graphics2d.setFont(new Font("宋体", Font.BOLD, 18));
		Random random = new Random();// 生成随机数
		int index = random.nextInt(words.size());
		String word = words.get(index-1);// 获得成语
		// 定义x坐标
		int x = 10;
		for (int i = 0; i &amp;lt; word.length(); i++) {
			// 随机颜色
			graphics2d.setColor(new Color(20 + random.nextInt(110), 20 + random
					.nextInt(110), 20 + random.nextInt(110)));
			// 旋转 -30 --- 30度
			int jiaodu = random.nextInt(60) - 30;
			// 换算弧度
			double theta = jiaodu * Math.PI / 180;
			// 获得字母数字
			char c = word.charAt(i);
			// 将c 输出到图片
			graphics2d.rotate(theta, x, 20);
			graphics2d.drawString(String.valueOf(c), x, 20);
			graphics2d.rotate(-theta, x, 20);
			x += 40;
		}
		&lt;a target="_self" href="https://pangyd.com/">// 将验证码内容保存session&lt;/a>
		request.getSession().setAttribute("checkcode_session", word);
		// 步骤五 绘制干扰线
		graphics.setColor(getRandColor(160, 200));
		int x1;
		int x2;
		int y1;
		int y2;
		for (int i = 0; i &amp;lt; 30; i++) {
			x1 = random.nextInt(width);
			x2 = random.nextInt(12);
			y1 = random.nextInt(height);
			y2 = random.nextInt(12);
			graphics.drawLine(x1, y1, x1 + x2, x2 + y2);
		}
		// 将上面图片输出到浏览器 ImageIO
		graphics.dispose();// 释放资源
		ImageIO.write(bufferedImage, "jpg", response.getOutputStream());
	}
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}
	/**
	 * 取其某一范围的color
	 * @param fc int 范围参数1
	 * @param bc int 范围参数2
	 * @return Color
	 */
	private Color getRandColor(int fc, int bc) {
		&lt;a target="_self" href="https://pangyd.com/">// 取其随机颜色&lt;/a>
		Random random = new Random();
		if (fc &amp;gt; 255) {
			fc = 255;
		}
		if (bc &amp;gt; 255) {
			bc = 255;
		}
		int r = fc + random.nextInt(bc - fc);
		int g = fc + random.nextInt(bc - fc);
		int b = fc + random.nextInt(bc - fc);
		return new Color(r, g, b);
	}
}
&lt;/string>&lt;/string>&lt;/pre></description></item><item><title>Java-Filter过滤器用于过滤整个项目的编码</title><link>https://pangyd.com/post/110-java-filter/</link><pubDate>Fri, 22 Sep 2017 20:00:54 +0800</pubDate><guid>https://pangyd.com/post/110-java-filter/</guid><description>&lt;p>整个分为实现类以及&lt;span>在web.xml文件中对编写的filter类进行&lt;a target="_self" href="https://pangyd.com/">注册&lt;/a>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;/p>&lt;pre lay-lang="Java" class="layui-code" skin="notepad">package cn.itcast.itcaststore.web.filter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
/**
 * 编码过滤器（用于统一项目编码）
 */
public class EncodingFilter implements Filter {
	public void init(FilterConfig filterConfig) throws ServletException {
&lt;pre>&lt;code>}
public void doFilter(ServletRequest request, ServletResponse response,
		FilterChain chain) throws IOException, ServletException {
	// 处理请求乱码
	HttpServletRequest httpServletRequest = (HttpServletRequest) request;
	HttpServletRequest myRequest = new MyRequest(httpServletRequest);
	// 处理响应乱码
	response.setContentType(&amp;quot;text/html;charset=utf-8&amp;quot;);
	chain.doFilter(myRequest, response);
}
public void destroy() {

}
&lt;/code>&lt;/pre>
&lt;p>}
// 自定义request对象
class MyRequest extends HttpServletRequestWrapper {
private HttpServletRequest request;
private boolean hasEncode;
public MyRequest(HttpServletRequest request) {
super(request);// super必须写
this.request = request;
}
// 对需要增强方法 进行覆盖
@SuppressWarnings({ &amp;ldquo;unchecked&amp;rdquo;, &amp;ldquo;rawtypes&amp;rdquo; })
@Override
public Map getParameterMap() {
// 先获得请求方式
String method = request.getMethod();
if (method.equalsIgnoreCase(&amp;ldquo;post&amp;rdquo;)) {
// post请求
try {
// 处理post乱码
request.setCharacterEncoding(&amp;ldquo;utf-8&amp;rdquo;);
return request.getParameterMap();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
} else if (method.equalsIgnoreCase(&amp;ldquo;get&amp;rdquo;)) {
// get请求
Map&amp;lt;string, string[]=&amp;quot;&amp;quot;&amp;gt; parameterMap = request.getParameterMap();
if (!hasEncode) { // 确保get手动编码逻辑只运行一次
for (String parameterName : parameterMap.keySet()) {
String[] values = parameterMap.get(parameterName);
if (values != null) {
for (int i = 0; i &amp;lt; values.length; i++) {
try {
values[i] = new String(values[i].getBytes(&amp;ldquo;ISO-8859-1&amp;rdquo;),&amp;ldquo;utf-8&amp;rdquo;);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
}
hasEncode = true;
}
return parameterMap;
}
return super.getParameterMap();
}
@Override
public String getParameter(String name) {
@SuppressWarnings(&amp;ldquo;unchecked&amp;rdquo;)
Map&amp;lt;string, string[]=&amp;quot;&amp;quot;&amp;gt; parameterMap = getParameterMap();
String[] values = parameterMap.get(name);
if (values == null) {
return null;
}
return values[0]; // 取回参数的第一个值
}
@Override
public String[] getParameterValues(String name) {
@SuppressWarnings(&amp;ldquo;unchecked&amp;rdquo;)
Map&amp;lt;string, string[]=&amp;quot;&amp;quot;&amp;gt; parameterMap = getParameterMap();
String[] values = parameterMap.get(name);
return values;
}
}
&amp;lt;/string,&amp;gt;&amp;lt;/string,&amp;gt;&amp;lt;/string,&amp;gt;&lt;/pre>&lt;p>&lt;span>&lt;a target="_self" href="https://pangyd.com/">web.xml配置&lt;/a>&lt;/span>&lt;/p></description></item><item><title>Java项目实战经验—程序员成长的钥匙</title><link>https://pangyd.com/post/109-java/</link><pubDate>Thu, 21 Sep 2017 22:23:27 +0800</pubDate><guid>https://pangyd.com/post/109-java/</guid><description>&lt;p>Java就是用来做项目的！Java的主要应用领域就是企业级的项目开发！要想从事企业级的项目开发，你必须掌握如下要点：&lt;/p>&lt;p>1、掌握项目开发的基本步骤&lt;/p>&lt;p>2、具备极强的面向对象的分析与设计技巧&lt;/p>&lt;p>3、掌握用例驱动、以架构为核心的主流开发方法&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>没有人愿意自己一辈子就满足于掌握了一些代码实现的技巧，别人告诉你要实现什么，你就用代码堆砌来实现别人的要求！你必须学会从整个项目的角度去思考！你必须学会假如你是项目经理，你该如何思考！你必须学会假如你是架构师，你该如何思考！你必须掌握针对某个特定问题领域的分析方法！&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>关于基础知识：你可以看看这些名词或知识点，看是否能说出个一二三四来。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>JavaSE&lt;/p>&lt;p>----基本语法、数据类型、操作符等：int、long、Integer、Long、if、else、for、while&lt;/p>&lt;p>----面向对象：class（类）、Object（对象）、instance（实例）、state（状态）、behavior（行为）、field、method、new、可见性（访问控制）、attribute、property、package、import、static variable、class variable、instance variable、heap、method area、stack、GC（垃圾回收）、override、overload、对象转型(casting)、多态、this、super&lt;/p>&lt;p>----异常处理：理解编译期错误和运行期错误的区别、Exception、RuntimeException、checked exception、unchecked exception、try、catch、finally、throw new XXXException、throws XXXException、异常处理的基本原则&lt;/p>&lt;p>----数组与集合：数组的定义和使用方法、Collection、List、Set、Map、ArrayList、HashSet、HashMap、Iterator、equals、hashCode、Comparable、Comparator&lt;/p>&lt;p>----常用类：String、intern、常量池、StringBuffer、java.util.Date、SimpleDateFormat、Regex（正则表达式）&lt;/p>&lt;p>----反射机制：Class、Method、Field、invoke、newInstance、BeanUtils（apache-commons）、PropertyUtils（apache-commons）&lt;/p>&lt;p>----输入输出流：InputStream、OutputStream、Reader、Writer、Adapter设计模式与原始流类、Decorator设计模式与包装流类、对象序列化和反序列化&lt;/p>&lt;p>----多线程：Thread、Runnable、sleep、wait、notify、synchronized、lock&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>Servlet和JSP&lt;/p>&lt;p>----HttpServlet、doGet、doPost、HttpServletRequest、HttpServletResponse、request.getParameter()、request.setAttribute()、request.getAttribute()、request.getSession()、ServletContext、Filter、web.xml、tomcat、forward与redirect、http协议的无状态性、cookie、JSP Scope Object、&amp;lt;c:out …/&amp;gt;、&amp;lt;c:forEach …&amp;gt;&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>HTML与JavaScript&lt;/p>&lt;p>----你需要能够理解常见的网页标签、理解在网页中引入JavaScript的方法、以及JavaScript的基本语法与使用方法&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>以上，就是你进一步学习Java所必备的基本知识。特别是一些个专业术语和名词，看到这些名词，如果你像看到亲爹一样亲切，那么说明你对Java的基础知识就很熟悉了。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>接下来是SSH：&lt;/p>&lt;p>对于初学者来说，这三大框架被赋予了太多神秘的色彩，似乎它们是重中之重的知识！但是对于拥有多年Java开发经验的专业技术人员来说，对于那些Java牛人来说，却对这三大框架不太感冒！难道它们不重要吗？&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>现在很多企业都在用这三大框架，所以很多企业也把掌握这三大框架作为招聘的必备条件。不可否认的是，也有很多大型企业没有用这三大框架，这些企业经过多年发展，自身已经有一定的技术积累，也形成了自己独特的技术框架体系。这三大框架既可以说很重要，也可以说不重要。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>说重要的原因在于：这三大框架对JavaEE开发中所存在的普遍的问题，提供了优美的解决方案，它们蕴含了这个行业中最NB的开发人员的努力和想法，所以，学习这三大框架，你就可以窥探到这些处于技术巅峰的牛人们究竟对一个问题是怎么想的，通过一种什么样的设计思路去解决问题的。所以，对于你来说，你没有太多项目开发的经验，经验是什么？经验就是你知道可能会遇到哪些问题，针对哪个问题可以有哪些解决方法，在某个情景下，哪种解决方法是较好的，哪种方法不太好等等！如果你没做过什么项目，你根本就不会去意识到你可能会遇到哪些问题，而这些问题往往又是非常关键的！解决得不好，会影响到你的程序的稳定性、可扩展性等等！三大框架就给初学者提供了了解你以后可能会遇到哪些问题，以及针对这些问题的解决方案！&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>当你了解了这三大框架为什么是重要的，那么你也就能理解，为什么这三大框架也可以说是不重要的。如果你曾经开发过很多项目，你碰到了各种各样的问题，凭着你的技术功底，逐个击破了这些问题，在这些人眼里，三大框架（是不是还有N个框架？呵呵）都是浮云！&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>你属于哪一种人呢？如果你没有太多项目开发经验，那么三大框架对于你来说就是非常重要的！而且，由此你也知道了该怎么去学这三大框架。对于三大框架的学习而言，着力点在于给你展示问题，并触发你自己主动的思考，我们鼓励你提出自己的想法，也许你的想法很白痴，但那毕竟是你自己的想法，如果你不知道牛人的想法，那你怎么知道自己的想法是很白痴的呢？在这种思想的碰撞过程中，你就会逐渐提高自己！所以，三大框架学完之后，你不应该只是看到一大堆配置文件，你不应该只是看到了一些Action，一些Service，一些映射文件，你不应该只知道session.save/update/delete，你不应该只是知道struts2中有一堆interceptor，你不应该只是看到一堆jar包……&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>如果你只是知道拷贝一堆jar包，定义一系列配置文件之后，SSH三大框架就能够运行起来了，也可以给你干活了，那么，很悲哀的是，你仍然没有掌握三大框架的精粹！请你回答以下问题：&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>Struts2：&lt;/p>&lt;p>为什么每次请求都要创建一个Action对象？&lt;/p>&lt;p>ModelDriven拦截器的配置中refreshModelBeforeResult解决了什么问题？&lt;/p>&lt;p>为什么在web.xml中配置的StrutsPrepareAndExecuteFilter要过滤所有的请求？&lt;/p>&lt;p>请你给我谈谈ValueStack？&lt;/p>&lt;p>Struts2是如何实现MVC设计模式的？&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>Spring：&lt;/p>&lt;p>你为什么要用Spring？&lt;/p>&lt;p>请你聊一聊IOC/DI？&lt;/p>&lt;p>什么是声明式的事务管理？为什么要使用声明式的事务管理？Spring如何实现声明式的事务管理？&lt;/p>&lt;p>把spring和hibernate集成，定义事务管理特性的时候，为何要将除了添加、删除、更新操作之外的方法，即主要执行查询任务的方法定义为read-only？&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>Hibernate：&lt;/p>&lt;p>请你谈谈你对OR映射的理解？&lt;/p>&lt;p>很多人说Hibernate不适合大项目，性能有问题，你是如何理解的？&lt;/p>&lt;p>Hibernate为什么一定要定义一个数据库标识？&lt;/p></description></item><item><title>程序猿幽默你是学不来的！</title><link>https://pangyd.com/post/108/</link><pubDate>Wed, 20 Sep 2017 20:47:51 +0800</pubDate><guid>https://pangyd.com/post/108/</guid><description>&lt;p>1、程序员找不女朋友的原因&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>程序员问禅师：“大师,我身体健康,思想端正,各方面都不错，为何就是找不到女朋友呢?”&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>禅师浅笑,答：“原因很简单，不过若想我告诉你，你需先写一段java代码。”&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>青年略一沉吟，写完了。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>“再写一段C#” 写完了，&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>“再写一段php” 写完了，&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>“再写一段js”，写完了，&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>“这就是原因” 。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>2、技术宅男如何把妹？&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>1.自制系统盘内置马儿随时知道MM在做什么，计划任务定期搞崩系统从而保持用户粘性；&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>2.给MM推荐自制APP，随时知道mm位置给她惊喜；&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>3.经过一段时间你就积累了大量数据，做一下数据挖掘就知道她的一切喜好习惯；&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>4.将该应用免费开放给更多宅男，于是有了海量数据。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>——这就是云把妹。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>3、程序员如何制造就业机会&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>一老板坐飞机,旁边一刚毕业程序员拿着杂志看,一边看一边念叨:云计算要火?&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>老板听了,回去问VP:什么是云计算?&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>VP回去告诉总监:我们可能要做云计算;&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>总监回去告诉经理:公司要做云计算,马上招人.&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>经理面试,有一个就是前几天那个拿杂志的毕业生,&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>毕业生说,没想到云计算真的要火?&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>——所以机会还是给有准备的人。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>4、世界上最没用的几句话&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>1、警察：不要跑！&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>2、国足：必胜！&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>3、老师：同学们不要睡了！&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>4、病人：医生，您轻点儿！&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>5、父母：孩子，不要闹了 ！&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>6、罪犯：我是冤枉啊！&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>7、女人：不要嘛！&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>8、男人：我发誓！&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>9、程序员：这个不能实现！&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>5、程序员找不到对象&lt;/p>&lt;p>&lt;br>&lt;/p></description></item><item><title>404-各种网页状态返回码含义！</title><link>https://pangyd.com/post/107-404/</link><pubDate>Tue, 19 Sep 2017 21:02:11 +0800</pubDate><guid>https://pangyd.com/post/107-404/</guid><description>&lt;p>&lt;span>我们在访问一个网页的时候经常会看到400、404、500这样的错误页面，有时候脑子里会一闪而过，为什么页面上会出现这些数字，它们是什么意思呢？&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;h2>&lt;span>&lt;strong>&lt;span>不同的错误页面其实代表不同的含义，今天和大家说说这几个页面的一些情况&lt;/span>&lt;/strong>&lt;span>&lt;strong>&lt;span>。&lt;/span>&lt;/strong>&lt;strong>&lt;span>像&lt;/span>&lt;/strong>&lt;span>400、404、500这样的数字被称为&lt;/span>&lt;span>&lt;strong>&lt;span>状态码。&amp;nbsp;&lt;/span>&lt;/strong>&lt;/span>&lt;/span>&lt;/span>&lt;/h2>&lt;p>&lt;span>&lt;span>&lt;span>&lt;strong>&lt;span>&lt;br>&lt;/span>&lt;/strong>&lt;/span>&lt;/span>&lt;/span>&lt;/p>&lt;h2 style="text-align: center">&lt;strong>&lt;span>&lt;span>HTTP状态码（图一）&lt;/span>&lt;/span>&lt;/strong>&lt;span>&lt;br>&lt;/span>&lt;/h2>&lt;p style="text-align: center">&lt;img data-ratio="1" data-src="https://pangyd.com/uploads/2017/09/74c10f869f038762.jpg" data-type="jpeg" data-w="640" title="图5：笑出腹肌的程序猿搞笑趣图" _width="auto" class="" src="https://pangyd.com/uploads/2017/09/74c10f869f038762.jpg" data-fail="0">&lt;/p>&lt;p style="text-align: center">&lt;br>&lt;/p>&lt;p>&lt;span>&lt;strong>&lt;span>注释：&lt;/span>&lt;/strong>&lt;/span>&lt;/p>&lt;blockquote>&lt;ul class="list-paddingleft-2">&lt;li>&lt;p>&lt;span>&lt;strong>&lt;span>301&lt;/span>&lt;/strong>&lt;span>—永久移动。被请求的资源已被永久移动位置；&lt;/span>&lt;/span>&lt;/p>&lt;/li>&lt;li>&lt;p>&lt;span>&lt;strong>&lt;span>302&lt;/span>&lt;/strong>&lt;span>—请求的资源现在临时从不同的 URI 响应请求；&lt;/span>&lt;/span>&lt;/p>&lt;/li>&lt;li>&lt;p>&lt;span>&lt;strong>&lt;span>305&lt;/span>&lt;/strong>&lt;span>—使用代理。被请求的资源必须通过指定的代理才能被访问；&lt;/span>&lt;/span>&lt;/p>&lt;/li>&lt;li>&lt;p>&lt;span>&lt;strong>&lt;span>307&lt;/span>&lt;/strong>&lt;span>—临时跳转。被请求的资源在临时从不同的URL响应请求；&lt;/span>&lt;/span>&lt;/p>&lt;/li>&lt;li>&lt;p>&lt;span>&lt;strong>&lt;span>400&lt;/span>&lt;/strong>&lt;span>—错误请求；&lt;/span>&lt;/span>&lt;/p>&lt;/li>&lt;li>&lt;p>&lt;span>&lt;strong>&lt;span>402&lt;/span>&lt;/strong>&lt;span>—需要付款。该状态码是为了将来可能的需求而预留的，用于一些数字货币或者是微支付；&lt;/span>&lt;/span>&lt;/p>&lt;/li>&lt;li>&lt;p>&lt;span>&lt;strong>&lt;span>403&lt;/span>&lt;/strong>&lt;span>—禁止访问。服务器已经理解请求，但是拒绝执行它；&lt;/span>&lt;/span>&lt;/p>&lt;/li>&lt;li>&lt;p>&lt;span>&lt;strong>&lt;span>404&lt;/span>&lt;/strong>&lt;span>—找不到对象。请求失败，资源不存在；&lt;/span>&lt;/span>&lt;/p>&lt;/li>&lt;li>&lt;p>&lt;span>&lt;strong>&lt;span>406&lt;/span>&lt;/strong>&lt;span>—不可接受的。请求的资源的内容特性无法满足请求头中的条件，因而无法生成响应实体；&lt;/span>&lt;/span>&lt;/p>&lt;/li>&lt;/ul>&lt;/blockquote>&lt;p>&lt;br>&lt;/p>&lt;p style="text-align: center">&lt;span>&lt;strong>&lt;span>HTTP状态码（图二）&lt;/span>&lt;/strong>&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;img data-ratio="1" data-src="https://pangyd.com/uploads/2017/09/74c10f869f038762.jpg" data-type="jpeg" data-w="640" title="图6：笑出腹肌的程序猿搞笑趣图" _width="auto" class="" src="https://pangyd.com/uploads/2017/09/74c10f869f038762.jpg" data-fail="0">&lt;/p>&lt;p style="text-align: center">&lt;br>&lt;/p>&lt;p>&lt;span>&lt;strong>&lt;span>注释：&lt;/span>&lt;/strong>&lt;/span>&lt;/p>&lt;blockquote>&lt;ul class="list-paddingleft-2">&lt;li>&lt;p>&lt;span>&lt;strong>&lt;span>408&lt;/span>&lt;/strong>&lt;span>—请求超时；&lt;/span>&lt;/span>&lt;/p>&lt;/li>&lt;li>&lt;p>&lt;span>&lt;strong>&lt;span>409&lt;/span>&lt;/strong>&lt;span>—冲突。由于和被请求的资源的当前状态之间存在冲突，请求无法完成；&lt;/span>&lt;/span>&lt;/p>&lt;/li>&lt;li>&lt;p>&lt;span>&lt;strong>&lt;span>410&lt;/span>&lt;/strong>&lt;span>—遗失的。被请求的资源在服务器上已经不再可用，而且没有任何已知的转发地址；&lt;/span>&lt;/span>&lt;/p>&lt;/li>&lt;li>&lt;p>&lt;span>&lt;strong>&lt;span>413&lt;/span>&lt;/strong>&lt;span>—响应实体太大。服务器拒绝处理当前请求，请求超过服务器所能处理和允许的最大值。&lt;/span>&lt;/span>&lt;/p>&lt;/li>&lt;li>&lt;p>&lt;span>&lt;strong>&lt;span>417&lt;/span>&lt;/strong>&lt;span>—期望失败。在请求头 Expect 中指定的预期内容无法被服务器满足；&lt;/span>&lt;/span>&lt;/p>&lt;/li>&lt;li>&lt;p>&lt;span>&lt;strong>&lt;span>418&lt;/span>&lt;/strong>&lt;span>—我是一个茶壶。超文本咖啡罐控制协议，但是并没有被实际的HTTP服务器实现；&lt;/span>&lt;/span>&lt;/p>&lt;/li>&lt;li>&lt;p>&lt;span>&lt;strong>&lt;span>420&lt;/span>&lt;/strong>&lt;span>—方法失效。&lt;/span>&lt;/span>&lt;/p>&lt;/li>&lt;li>&lt;p>&lt;span>&lt;strong>&lt;span>422&lt;/span>&lt;/strong>&lt;span>—不可处理的实体。请求格式正确，但是由于含有语义错误，无法响应；&lt;/span>&lt;/span>&lt;/p>&lt;/li>&lt;li>&lt;p>&lt;span>&lt;strong>&lt;span>500&lt;/span>&lt;/strong>&lt;span>—服务器内部错误。服务器遇到了一个未曾预料的状况，导致了它无法完成对请求的处理；&lt;/span>&lt;/span>&lt;/p>&lt;/li>&lt;/ul>&lt;/blockquote>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>404 是我们比较常见的错误页面，来看看有哪些有趣的设计~&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;img data-s="300,640" data-type="png" data-src="https://pangyd.com/uploads/2017/09/74c10f869f038762.jpg" class="" data-ratio="0.9108695652173913" data-w="460" _width="61%" src="https://pangyd.com/uploads/2017/09/74c10f869f038762.jpg" data-fail="0">&lt;/p>&lt;p style="text-align: center">&lt;img data-s="300,640" data-type="jpeg" data-src="https://pangyd.com/uploads/2017/09/74c10f869f038762.jpg" class="" data-ratio="0.7275" data-w="400" src="https://pangyd.com/uploads/2017/09/74c10f869f038762.jpg" data-fail="0">&lt;/p></description></item><item><title>30 年编码经验浓缩的 10 条最佳实践</title><link>https://pangyd.com/post/106-30-10/</link><pubDate>Mon, 18 Sep 2017 18:19:21 +0800</pubDate><guid>https://pangyd.com/post/106-30-10/</guid><description>&lt;p>&lt;span>&lt;span>是什么使得代码更好?&lt;/span>&lt;/span>&lt;/p>&lt;p>良好的代码更易于阅读、理解、调试和修改，最重要的是它的缺陷也更少。显然，编写良好的代码需要更多的时间，但是从长远来看，它也具有更多的价值，因为这降低了维护的成本，而且具有更好的可重用性。&lt;/p>&lt;p>事实上，我们可以将好的代码等同为可重用的代码，这也是本篇文章罗列的许多技巧背后的驱动原则。作为一个要实现特定功能的开发者，代码可以实现你的短期目标，但如果没有其他人希望重用它(包括未来的自己)，这些代码一定会缺失某些东西。无论它是太复杂，还是太具体，在不同情况下都有很大可能会出错，或者不被其他开发者信任。&lt;/p>&lt;p>我发现，只要尝试坚持将下面的最佳实践应用于你编写的所有代码(包括你的实验和原型)，无论你现在的经验水平如何，都会编写出更好的代码。&lt;/p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" title="30年编程经验浓缩的10条最佳实践" alt="30年编程经验浓缩的10条最佳实践">&lt;br>&lt;p>&lt;span>&lt;span>1&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>遵循单一职责原则&lt;/span>&lt;/span>&lt;/p>&lt;p>函数是程序员的工具中最重要的抽象形式。它们能更多地被重复使用，你需要编写的代码就越少，代码也因此变得更可靠。较小的函数遵循单一职责原则更有可能被重复使用。&lt;/p>&lt;p>&lt;span>&lt;span>2&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>尽量减少共享状态&lt;/span>&lt;/span>&lt;/p>&lt;p>你应该尽量减少函数之间的隐式共享状态，无论它是文件作用域的变量还是对象的成员字段，这有利于明确要求把值作为参数。当能明确地显示函数需要什么才可以产生所需的结果时，代码会变得更容易理解和重用。&lt;/p>&lt;p>对此的一个推论是，在一个对象中，相对于成员变量，你更应该优先选择静态的无状态变量 (static stateless variables)。&lt;/p>&lt;p>&lt;span>&lt;span>3&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>将“副作用”局部化&lt;/span>&lt;/span>&lt;/p>&lt;p>理想的副作用(例如：打印到控制台、日志记录、更改全局状态、文件系统操作等)应该被放置到单独的模块中，而不是散布在整个代码里面。函数中的一些“副作用”功能往往违反了单一职责原则。&lt;/p>&lt;p>&lt;span>&lt;span>4&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>优先使用不变的对象&lt;/span>&lt;/span>&lt;/p>&lt;p>如果一个对象的状态在其构造函数中仅被设置一次，并且从不再次更改，则调试会变得更加容易，因为只要构造正确就能保持有效。这也是降低软件项目复杂性的最简单方法之一。&lt;/p>&lt;p>&lt;span>&lt;span>5&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>接口高于类&lt;/span>&lt;/span>&lt;/p>&lt;p>接收接口的函数(或 C++ 中的模板参数和概念)比在类上运行的函数更具可重用性。&lt;/p>&lt;p>&lt;span>&lt;span>6&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>对模块应用良好的原则&lt;/span>&lt;/span>&lt;/p>&lt;p>寻找机会将软件项目分解成更小的模块(例如库和应用程序)，以促进模块级别的重用。对于模块，应该遵循的一些关键原则是：&lt;/p>&lt;p>尽可能减少依赖&lt;/p>&lt;p>每个项目应该有一个明确的职责&lt;/p>&lt;p>不要重复自身&lt;/p>&lt;p>你应该努力使你的项目保持小巧和明确。&lt;/p>&lt;p>&lt;span>&lt;span>7&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>避免继承&lt;/span>&lt;/span>&lt;/p>&lt;p>在面向对象编程中，继承 —— 特别是和虚拟函数结合使用时，在可重用性方面往往是一条死胡同。我很少有成功的使用或编写重载类的库的经历。&lt;/p>&lt;p>&lt;span>&lt;span>8&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>将测试作为设计和开发的一部分&lt;/span>&lt;/span>&lt;/p>&lt;p>我不是测试驱动开发的坚定分子，但开始编码时先编写测试代码会使得代码十分自然地遵循许多指导原则。这也有助于尽早发现错误。不过要注意避免编写无用的测试，良好的编码实践意味着更高级别的测试(例如单元测试中的集成测试或特征测试)在揭示缺陷方面更有效。&lt;/p>&lt;p>&lt;span>&lt;span>9&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>优先使用标准的库&lt;/span>&lt;/span>&lt;/p>&lt;p>我经常看到更好版本的 std::vector 或 std::string，但这几乎总是浪费时间和精力。一个明显的事实是 —— 你正在为一个新的地方引入 bug，其他开发者也不太可能重用你的代码，因为没有被广泛理解、支持和测试。&lt;/p>&lt;p>&lt;span>&lt;span>10&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;span>避免编写新的代码&lt;/span>&lt;/span>&lt;/p>&lt;p>这是每个程序员都应遵循的最重要的教诲：最好的代码就是还没写的代码。你写的代码越多，你将遇到的问题就越多，查找和修复错误就越困难。&lt;/p>&lt;p>在写一行代码之前先问一问自己，有没有一个工具、函数或者库已经实现了你所需要的功能?你真的需要自己实现这个功能，而不是调用一个已经存在的功能吗?&lt;/p>&lt;p>&lt;span>&lt;span>写在最后的话&lt;/span>&lt;/span>&lt;/p>&lt;p>我发现编程是一门与学习艺术或运动非常相似的技能，你通过刻意的练习和从别人的经验中&lt;a target="_self" href="https://pangyd.com/">学习&lt;/a>会得到更好的结果。不断提升你产出的代码质量有助于你成为更优秀的&lt;a target="_self" href="https://pangyd.com/">程序员&lt;/a>。&lt;/p></description></item><item><title>java和JavaScript究竟是什么关系？</title><link>https://pangyd.com/post/105-javajavascript/</link><pubDate>Sun, 17 Sep 2017 21:27:42 +0800</pubDate><guid>https://pangyd.com/post/105-javajavascript/</guid><description>&lt;p>&lt;span>犹记得刚刚接触Java的时候，有一天突然看见了JavaScript，第一反应就是：这是什么?跟Java这么像，莫非它俩之间有什么不可告人的关系?&lt;/span>&lt;/p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" title="【java和javascript究竟是什么关系？】" alt="【java和javascript究竟是什么关系？】">&lt;br>&lt;p>这就得从他们诞生时开始说起：&lt;/p>&lt;p>1994年的时候，网景公司(Netscape)发布了Navigator浏览器0.9版。这是历史上第一个比较成熟的网络浏览器，&lt;a target="_self" href="https://pangyd.com/">轰动一时&lt;/a>。但是，这个版本的浏览器只能用来浏览，不具备与访问者互动的能力。因此，网景公司急需一种网页脚本语言，使得浏览器可以与网页互动。1995年Sun公司将Oak语言改名为Java，正式向市场推出，并且打出了“一次编写，到处运行(Write once，run anywhere)”的宣传口号。网景公司非常看好Java，决定与Sun公司结成联盟。仅一个月后，网景公司做出决定，未来的网页脚本语言，必须看上去与Java足够相似，但是比Java简单。程序员Brendan Eich被指定为这种“简化版Java语言”的设计师。&lt;/p>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" alt="">&lt;br>&lt;p>但是Brendan Eich对Java丝毫没有兴趣，用了10天时间就设计出了JavaScript。总体的设计思路是：(1)借鉴C语言的基本语法;(2)借鉴Java语言的数据类型和内存管理;(3)借鉴Scheme语言，将函数提升到“第一等公民”(first class)的地位;(4)借鉴Self语言，使用基于原型(prototype)的继承机制。也就是说，Java Script在设计时所参考的对象不包括 Java，而包括了像 Self 和 Scheme 这样的语言，它实际上是函数式编程和面向对象编程两种语言风格的混合产物。并且javascript最初的名字并不是javascript，而是LiveScript，名字中的“Java”是经过SUN Microsystems公司授权的。&lt;/p>&lt;p>简单说java和JavaScript是两个不同的语言。&lt;/p>&lt;p>1 语言特点：&lt;/p>&lt;p>1.1 弱类型：&lt;/p>&lt;p>JavaScript在变量声明的时候并不严格区分数据类型，(var 变量名)，不像java那样严格(类型：变量名)。也就说，Javascript面前一切平等，在他眼里大家都是人，而在java就有所不同，男人、女人、什么的……&lt;/p>&lt;p>基于这个特性，javascript在很多时候会都可以写的比java简洁，比如函数的声明等。&lt;/p>&lt;p>1.2 动态语言：&lt;/p>&lt;p>java在定义了一个数组的长度以后就不能再改变了，但是javascript却可以。并且java一个数组只能放同一种类型，但javascript可以在一个数组内加不同数据类型的数据。可以说Java比较死心眼，javascript则比较灵活。&lt;/p>&lt;p>1.3 脚本语言:&lt;/p>&lt;p>Java等后台语言都是编译后执行的，但是javascript却是边编译边执行。&lt;/p>&lt;p>2 数据类型&lt;/p>&lt;p>2.1 基础数据类型：&lt;/p>&lt;p>Java有八大数据类型：byte,short,intlong,float,double,char,Boolean。感觉javascript把上面的整理成了三种原始类型：number,string,boolean。另外还有两个特殊的原始类型是：null和undefined。&lt;/p>&lt;p>2.2 变量&lt;/p>&lt;p>Java：数据类型 变量名=值;&lt;/p>&lt;p>Javascript：var 变量名=值;数组&lt;/p>&lt;p>Java：&lt;/p>&lt;p>类型[] 数组名=new 类型[数量];&lt;/p>&lt;p>类型[] 数组名=new 类型[]{元素1，元素2…};&lt;/p>&lt;p>Javascript：&lt;/p>&lt;p>var 数组名=[];&lt;/p>&lt;p>var 数组名=new Array();&lt;/p>&lt;p>3 函数：&lt;/p>&lt;p>Java：返回值&lt;a target="_self" href="https://pangyd.com/">类型&lt;/a> 函数名(类型 参数1，类型 参数2…){}&lt;/p>&lt;p>Javascript：function 函数名(参数1，参数2…){}&lt;/p>&lt;p>两者用途&lt;/p>&lt;p>java广泛应用于个人PC、数据中心、游戏控制台、科学超级计算机、移动电话和&lt;a target="_self" href="https://pangyd.com/">互联网&lt;/a>等。&lt;/p></description></item><item><title>真正的Java学习从入门到精通，只需拿下这6点！</title><link>https://pangyd.com/post/104-java-6/</link><pubDate>Sat, 16 Sep 2017 19:56:40 +0800</pubDate><guid>https://pangyd.com/post/104-java-6/</guid><description>&lt;blockquote class="" data-author="易点微信编辑器" data-url="https://wxedit.yead.net">&lt;section>&lt;section style="text-align: inherit">&lt;section>&lt;section>&lt;span class="">&lt;span data-brushtype="text">划重点&lt;/span>&lt;/span>&lt;/section>&lt;section class="">&lt;/section>&lt;/section>&lt;section data-style="box-sizing: border-box;line-height: 30px; background-color: rgb(244, 244, 244);">&lt;p>&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;初入学习Java不知道该何从下手？&lt;/p>&lt;p>&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;有了基础知识，提升技术不知该如何学习？&lt;/p>&lt;p>&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;今天分享一个技能大篇，帮助你实现技术的提升，薪资的高涨，认真看哦！&lt;/p>&lt;/section>&lt;/section>&lt;/section>&lt;/blockquote>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;/p>&lt;section data-author="Wxeditor">&lt;article class="" data-author="Wxeditor">&lt;section style="text-align: center">&lt;section class="" style="text-align: left">&lt;section>&lt;p>&lt;span>&lt;span>一、工具篇JDK&lt;/span>&lt;/span>&lt;/p>&lt;/section>&lt;/section>&lt;section class="" style="text-align: left">&lt;/section>&lt;/section>&lt;/article>&lt;/section>&lt;p>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>JDK是整个Java的核心，包括了Java运行环境（Java Runtime Envirnment），一堆Java工具和Java基础的类库(rt.jar)。不论什么Java应用服务器实质都是内置了某个版本的JDK。因此掌握JDK是学好Java的第一步。最主流的JDK是Sun公司发布的JDK，除了Sun之外，还有很多公司和组织都开发了自己的JDK，例如IBM公司开发的JDK，BEA公司的Jrocket，还有GNU组织开发的JDK等等。其中IBM的JDK包含的JVM（Java Virtual Machine）运行效率要比Sun JDK包含的JVM高出许多。而专门运行在x86平台的Jrocket在服务端运行效率也要比Sun JDK好很多。但不管怎么说，我们还是需要先把Sun JDK掌握好。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;/p>&lt;section data-author="Wxeditor">&lt;article class="" data-author="Wxeditor">&lt;section>&lt;h3 class="">1、 JDK的下载和安装&lt;/h3>&lt;/section>&lt;/article>&lt;/section>&lt;p>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>JDK又叫做J2SE（Java2 SDK Standard Edition），可以从Sun的Java网站上下载到，&lt;a href="https://java.sun.com/j2se/downloads.html" target="_blank" class="link link-normal">网页链接&lt;/a>&amp;nbsp;，JDK当前最新的版本是J2SDK1.4.2，建议下载该版本的JDK，下载页面在这里：&lt;a href="https://java.sun.com/j2se/1.4.2/download.html" target="_blank" class="link link-normal">网页链接&lt;/a>。下载好的JDK是一个可执行安装程序，默认安装完毕后会在C:\Program Files\Java\目录下安装一套JRE（供浏览器来使用），在C:\j2sdk1.4.2下安装一套JDK（也包括一套JRE）。然后我们需要在环境变量PATH的最前面增加java的路径C:\j2sdk1.4.2\bin。这样JDK就安装好了。&lt;/span>&lt;br>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;/p>&lt;section data-author="Wxeditor">&lt;article class="" data-author="Wxeditor">&lt;section>&lt;h3 class="">2、 JDK的命令工具&lt;/h3>&lt;/section>&lt;/article>&lt;/section>&lt;p>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;ul class=" list-paddingleft-2">&lt;li>&lt;p>&lt;span>JDK的最重要命令行工具：&lt;/span>&lt;br>&lt;span>java： 启动JVM执行class&lt;/span>&lt;br>&lt;span>javac： Java编译器&lt;/span>&lt;br>&lt;span>jar： Java打包工具&lt;/span>&lt;br>&lt;span>javadoc： Java文档生成器&lt;/span>&lt;br>&lt;br>&lt;span>这些命令行必须要非常非常熟悉，对于每个参数都要很精通才行。对于这些命令的学习，JDK Documentation上有详细的文档。&amp;nbsp;&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;/p>&lt;/li>&lt;/ul>&lt;p>&lt;/p></description></item><item><title>Java Web 网站技术架构演化和总结</title><link>https://pangyd.com/post/103-java-web/</link><pubDate>Fri, 15 Sep 2017 20:00:42 +0800</pubDate><guid>https://pangyd.com/post/103-java-web/</guid><description>&lt;p style="text-align: justify">&lt;b>[&lt;a target="_self" href="https://pangyd.com/">分享&lt;/a>]&lt;/b>工作也有几多年了，无论是身边遇到的还是耳间闻到的，多多少少也积攒了自己的一些经验和思考，当然，博主并没有太多接触高大上的分布式架构实践，相对比较零碎，随时补充。&lt;/p>&lt;p style="text-align: justify">&lt;span>俗话说的好，冰冻三尺非一日之寒，滴水穿石非一日之功，罗马也不是一天就建成的，当然对于我们开发人员来说，一个好的架构也不是一蹴而就的。&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>初始搭建&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>开始的开始，就是各种框架一搭，然后扔到Tomcat容器中跑就是了，这时候我们的文件，数据库，应用都在一个服务器上。&lt;/span>&lt;/p>&lt;p>&lt;img class="" data-ratio="0.84375" data-src="https://pangyd.com/uploads/2017/09/74c10f869f038762.jpeg" data-type="jpeg" data-w="640" height="562" width="666" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-fail="0">&lt;span>服务分离&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>随着系统的的上线，用户量也会逐步上升，很明显一台服务器已经满足不了系统的负载，这时候，我们就要在服务器还没有超载的时候，提前做好准备。&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>由于我们是单体架构，优化架构在短时间内是不现实的，增加机器是一个不错的选择。这时候，我们可能要把应用和数据库服务单独部署，如果有条件也可以把文件服务器单独部署。&lt;/span>&lt;/p>&lt;p>&lt;img class="" data-ratio="0.870020964360587" data-src="https://pangyd.com/uploads/2017/09/74c10f869f038762.jpeg" data-type="jpeg" data-w="477" height="415" width="477" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-fail="0">&lt;span>反向代理&lt;/span>&lt;/p>&lt;p>&lt;img class="" data-ratio="0.4378531073446328" data-src="https://pangyd.com/uploads/2017/09/74c10f869f038762.jpeg" data-type="jpeg" data-w="354" height="155" width="354" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-fail="0">&lt;/p>&lt;p style="text-align: justify">&lt;span>为了提升服务处理能力，我们在Tomcat容器前加一个代理服务器，我一般使用Nginx，当然你如果更熟悉apache也未尝不可。&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>用户的请求发送给反向代理，然后反向代理把请求转发到后端的服务器。&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>严格意义上来说，Nginx是属于web服务器，一般处理静态html、css、js请求，而Tomcat属于web容器，专门处理JSP请求，当然Tomcat也是支持html的，只是效果没Nginx好而已。&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>反向代理的优势，如下：&lt;/span>&lt;/p>&lt;ul class=" list-paddingleft-2">&lt;li>&lt;p style="text-align: justify">&lt;span>隐藏真实后端服务&lt;/span>&lt;/p>&lt;/li>&lt;li>&lt;p style="text-align: justify">&lt;span>负载均衡集群&lt;/span>&lt;/p>&lt;/li>&lt;li>&lt;p style="text-align: justify">&lt;span>高可用集群&lt;/span>&lt;/p>&lt;/li>&lt;li>&lt;p style="text-align: justify">&lt;span>缓存静态内容实现动静分离&lt;/span>&lt;/p>&lt;/li>&lt;li>&lt;p style="text-align: justify">&lt;span>安全限流&lt;/span>&lt;/p>&lt;/li>&lt;li>&lt;p style="text-align: justify">&lt;span>静态文件压缩&lt;/span>&lt;/p>&lt;/li>&lt;li>&lt;p style="text-align: justify">&lt;span>解决多个服务跨域问题&lt;/span>&lt;/p>&lt;/li>&lt;li>&lt;p style="text-align: justify">&lt;span>合并静态请求(HTTP/2.0后已经被弱化)&lt;/span>&lt;/p>&lt;/li>&lt;li>&lt;p style="text-align: justify">&lt;span>防火墙&lt;/span>&lt;/p>&lt;/li>&lt;li>&lt;p style="text-align: justify">&lt;span>SSL以及http2&lt;/span>&lt;/p>&lt;/li>&lt;/ul>&lt;h1>&lt;span>动静分离&lt;/span>&lt;/h1>&lt;p>&lt;img class="" data-ratio="0.6956521739130435" data-src="https://pangyd.com/uploads/2017/09/74c10f869f038762.jpeg" data-type="jpeg" data-w="529" height="368" width="529" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" data-fail="0">&lt;/p></description></item><item><title>为什么程序员掌握改变世界的技术，却不能成为改变世界的人？</title><link>https://pangyd.com/post/102/</link><pubDate>Thu, 14 Sep 2017 20:24:17 +0800</pubDate><guid>https://pangyd.com/post/102/</guid><description>&lt;p>在当下的社会，一个高科技产品，必定搭载牛逼的程序才能实现各种功能！就比如我们手机上的APP，都是这些程序员开发出来的。但是问题来了：为什么程序员所掌握的技术那么牛，但是真正成为如马云的IT巨头却很少嗯？&lt;/p>&lt;p>正如我经常听到的程序员的通用别称：码农！就是形容代码搬运工！就如“农民工”，为什么会造房子，但是却造不出能够如“东方明珠”般宏伟的建筑！那么有人会说，造房子是需要用到地皮的，但是程序员写代码做程序是不受任何“客观因素”限制的！为什么他们就没有成功的作品呢？（有，但是少，或者不为人知）&lt;/p>&lt;p>我记得我之前跟一个程序员客户交流过，我问他你之前在大学时有没有帮别人写代码赚外快，他说有，我问他现在还会偶尔接私活赚外快吗？他说不会，为什么？他说：因为在接私活赚外快的时候，客户老是根据自己的喜好随意修改各种前期敲定的设计方案，而且根本听不进去程序员的意见。但是现在在大公司开发产品，公司很少参与设计，只是讲明白功能需求，怎么开发和怎么设计页面都是由自己的团队完成！我就问他：是不是公司这样的方式让你感觉很有成就感和受到了极大的尊重？他说，差不多就是那个意思！&lt;/p>&lt;p>就这个软件工程师反馈的信息来看，其实每个程序员或者每个人都会有这样的想法！每个人都极其需要得到尊重，极其需要自己的价值被提现，但是如果每个人都这样按照自己认为对的方向去努力去操作的话，就会很“自大”！每个技术型人才都会认为自己是专业的，自己的意见是最值得参考的，但是，就是因为有这样的想法，而导致程序员空有改变世界的能力，却连自己都改变不了！&lt;/p>&lt;p>决定一个APP产品的好坏不是看这个app是用了多少代码实现了多少功能，而是要看这个app（软件）实现的各种功能是不是真的满足了用户的诉求，和是不是页面和交换方式和使用体验让客户满意！当这个产品很优秀了以后，还需要完美的推广营销方案，把产品推给广大用户！这同时也说明了一点，会造房子不行，得会造成别人需要的房子！这也就是“产品经理”的作用的重要性！如马云，就是“早期的产品经理”！&lt;/p>&lt;p>程序员常有，而优秀的“产品经理不常有”！&lt;/p>&lt;p>此文没有任何贬低程序员的意思，希望大家不要误会！我尊重每一位在一线默默付出的每一个人，我也是一名基层默默付出的人，我只是感觉每个基层的付出者应该懂得更多！&lt;/p></description></item><item><title>【分享】Java并发面试题精选</title><link>https://pangyd.com/post/101-java/</link><pubDate>Wed, 13 Sep 2017 20:20:01 +0800</pubDate><guid>https://pangyd.com/post/101-java/</guid><description>&lt;p>1，什么是线程？&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>线程是操作系统能够进行运算调度的最小单位，它被包含在进程之中，是进程中的实际运作单位。程序员可以通过它进行多处理器编程，你可以使用多线程对运算密集型任务提速。比如，如果一个线程完成一个任务要100毫秒，那么用十个线程完成改任务只需10毫秒。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>2，线程和进程有什么区别？&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>线程是进程的子集，一个进程可以有很多线程，每条线程并行执行不同的任务。不同的进程使用不同的内存空间，而所有的线程共享一片相同的内存空间。每个线程都拥有单独的栈内存用来存储本地数据。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>3，如何在Java中实现线程？&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>两种方式：java.lang.Thread 类的实例就是一个线程但是它需要调用java.lang.Runnable接口来执行，由于线程类本身就是调用的Runnable接口所以你可以继承java.lang.Thread 类或者直接调用Runnable接口来重写run()方法实现线程。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>4，Java 关键字volatile 与 synchronized 作用与区别？&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>1，volatile&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>它所修饰的变量不保留拷贝，直接访问主内存中的。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>在Java内存模型中，有main memory，每个线程也有自己的memory (例如寄存器)。为了性能，一个线程会在自己的memory中保持要访问的变量的副本。这样就会出现同一个变 量在某个瞬间，在一个线程的memory中的值可能与另外一个线程memory中的值，或者main memory中的值不一致的情况。 一个变量声明为volatile，就意味着这个变量是随时会被其他线程修改的，因此不能将它cache在线程memory中。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>2，synchronized&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>当它用来修饰一个方法或者一个代码块的时候，能够保证在同一时刻最多只有一个线程执行该段代码。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>一、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时，一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>二、然而，当一个线程访问object的一个synchronized(this)同步代码块时，另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>三、尤其关键的是，当一个线程访问object的一个synchronized(this)同步代码块时，其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>四、当一个线程访问object的一个synchronized(this)同步代码块时，它就获得了这个object的对象锁。结果，其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>五、以上规则对其它对象锁同样适用。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>5，有哪些不同的线程生命周期？&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>当我们在Java程序中新建一个线程时，它的状态是New。当我们调用线程的start()方法时，状态被改变为Runnable。线程调度器会为Runnable线程池中的线程分配CPU时间并且讲它们的状态改变为Running。其他的线程状态还有Waiting，Blocked 和Dead。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>6，你对线程优先级的理解是什么？&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>每一个线程都是有优先级的，一般来说，高优先级的线程在运行时会具有优先权，但这依赖于线程调度的实现，这个实现是和操作系统相关的(OS dependent)。我们可以定义线程的优先级，但是这并不能保证高优先级的线程会在低优先级的线程前执行。线程优先级是一个int变量(从1-10)，1代表最低优先级，10代表最高优先级。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>7，什么是死锁(Deadlock)？如何分析和避免死锁？&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>死锁是指两个以上的线程永远阻塞的情况，这种情况产生至少需要两个以上的线程和两个以上的资源。&lt;/p></description></item><item><title>【励志】写给立志做码农的大学生</title><link>https://pangyd.com/post/100/</link><pubDate>Tue, 12 Sep 2017 19:30:31 +0800</pubDate><guid>https://pangyd.com/post/100/</guid><description>&lt;p>确定方向&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>选择比努力更重要。&lt;/p>&lt;p>&amp;nbsp; &amp;nbsp; &amp;nbsp; 关于方向的选择其实越早确定越好，生活中我们要面临无数个选择，前几天看的一个黑客相关的美剧中有句台词说的不错：&lt;/p>&lt;p>life is binary.&lt;/p>&lt;p>&amp;nbsp; &amp;nbsp; &amp;nbsp; 生活就是二进制，一个个0101组成的。每一次抉择，选了就是1，不选就是0。另外也有一句话说：“人一生要面临很多选择，但是真正能决定你命运的只有几个”。没错其实就是这样。&lt;/p>&lt;p>&amp;nbsp; &amp;nbsp; &amp;nbsp; 如果你是计算机专业的学生，那么到底是考研还是就业就是首先要面临的问题。本文是面向确定了毕业要工作的大学生的，所以关于这个抉择，不再赘述。&lt;/p>&lt;p>&amp;nbsp; &amp;nbsp; &amp;nbsp; 就业的话，本文标题是码农，实际是指所有计算机相关的技术工种。包括开发、测试、运维等。&lt;/p>&lt;p>很多选择本身并没有对错或优劣，只有适合不适合。&lt;/p>&lt;p>&amp;nbsp; &amp;nbsp; &amp;nbsp; 不要滥用勤能补拙，这个词语一度被很多人奉为圭臬，但同时成了枷锁。我相信这个词，但是要考虑现状，要考虑投资回报率。你在自己并不擅长或不感兴趣的领域深耕了四年，最后不一定能获得多少成绩。当然如果你能在毕业后继续深耕几年或许是可以的，但是我希望每一位大学生在毕业的时候都能有一份好的工作，并且如果你并不喜欢某一领域的话，那么我相信你一定不会坚持下去。所以我们一定要找到适合自己的方向！&lt;/p>&lt;p>&amp;nbsp; &amp;nbsp; &amp;nbsp; 那么如何发现自己对什么感兴趣呢？我也不知道很好的办法，我只知道一个朴素的方法——尝试。趁着年轻，就要多尝试。千万不要大三了都还不知道自己兴趣在哪，想做什么，适合什么。所以大一大二努力去碰钉子吧。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>算法还是开发？&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&amp;nbsp; &amp;nbsp; &amp;nbsp; 数据结构和算法很重要，无论是面试还是工作，无论你从事哪方面的技术。不过算法虽然重要，但并不适合每个人都花费大学全部的精力去钻研。&lt;/p>&lt;p>&amp;nbsp; &amp;nbsp; &amp;nbsp; 相信很多学校都有ACM竞赛相关的社团或组织。很不幸，我们学校没有，我大一的时候也花了很多精力刷题，但是硬件条件不太允许，氛围太缺乏。如果你觉得自己能够在ACM比赛中游刃有余，那么恭喜你，你可以一心一意搞算法。如果你觉得自己在这个过程中十分吃力，挫败感频生，那么也不要气馁，或许有另一条路是属于你的。选择开发，有算法功底深厚是很棒的事，但是仅仅只有算法同样是不够的，计算机海洋还有很多未知等着你探索。&lt;/p>&lt;p>&amp;nbsp; &amp;nbsp; &amp;nbsp; 算法岗包括数据挖掘、机器学习之类的（怎么样，高大上吧，反正我不懂）。要说明的是想做算法的同学最好选择读研继续深造，因为大企业在算法岗的招聘上对本科生是很不友好的。还是要申明一句，你做开发也不能忽视算法和数据结构，起码面试还是经常考的！记住一句：&lt;/p>&lt;p>算法功底好的人，运气都不会差。&lt;/p>&lt;p>&amp;nbsp; &amp;nbsp; &amp;nbsp; 对于本科生而言做开发还是相对容易的一条道路，不过开发的技术路线也是不胜枚举：前端、后台（PHP后台、Java后台等等）、移动端（安卓和iOS）、游戏开发、数据库（比如做DBA）……。这里我肯定不会去推荐你去学哪一种，我没有能力也不适合。只有你自己才能发现自己的兴趣以及好奇心之所在。&lt;/p>&lt;p>我能做的只是在浩如烟海的技术观点中，帮一个个本科生排疑解惑。&lt;/p>&lt;p>认识技术&lt;/p>&lt;p>&amp;nbsp; &amp;nbsp; &amp;nbsp; 关于技术，很多本科生都存在诸多误区。初学者总喜欢追随牛逼的技术，实在过于盲目，找准自己的定位最重要。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>误区1： 图形化的东西比非图形化东西更牛逼&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&amp;nbsp; &amp;nbsp; &amp;nbsp; 多见于初学者，尤其是计算机专业新生（我大一的时候就是）。当时学校教了点C语言，一直都是控制台程序，面对黑窗口，我就各种百度看看怎么弄出图形化的东西，那时候才知道GUI这个缩写是啥意思（当初知道这个缩写的全称还小激动了一下下，果然我还是太年轻了），然后知道了WIN32、MFC这些名词。确实只能说是知道名词。当时对着视频教程做了计算器，就是用VC++拖拖控件，视频里的人敲一句代码，我就敲一句。后面虽然弄出来了，但是感觉自己什么都不懂，只是依样画葫芦。这时我才意识到，还有很多基础没有打牢。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&amp;nbsp; &amp;nbsp; &amp;nbsp; 八卦一下，现在桌面客户端的开发工作并不多，所以大家谨慎选择这一技术方向。桌面端GUI技术一度火爆（MFC、Qt、WinForm、WPF、Swing……），但如今早已是互联网及移动互联网时代，所以大家真的要慎重选择。不过还是可以学习一下的，至少能加深你对编程语言以及设计模式的理解。&lt;/p></description></item><item><title>java程序员如何规划自己的职业生涯</title><link>https://pangyd.com/post/99-java/</link><pubDate>Mon, 11 Sep 2017 19:30:20 +0800</pubDate><guid>https://pangyd.com/post/99-java/</guid><description>&lt;p>IT行业越来越繁荣、成熟，随着移动互联网、java编程语言的普及，愈发有很多java程序员进入这个行业，java程序员面临自身能力提升时更多关注的是自身的硬实力，即技术功底、专业知识; java程序员如何规划自己的职业生涯，软技能的提升与硬实力同等重要，有时可能更为重要。&lt;/p>&lt;p>1. 专注力&lt;/p>&lt;p>在日常工作和生活中，我们可能时常被打断，特别是当我们进行编码工作时被打断后，往往需要半个小时或更长时间来找回当时的工作状态。挑选时间片段专注于单一任务的方法，可以帮助程序员从这种状态中脱离出来。当然自己也要学会建立防火墙，专注时间内的其它可能打扰自己的因素需要及时避免，如即时通信软件、微信等。专注于完成单一任务，不要期望并行任务完成得很好，经常性的被打断会造成专注力的缺失，对于程序员来说缺乏专注力是致命的。&lt;/p>&lt;p>￼&lt;/p>&lt;p>2. 时间管理&lt;/p>&lt;p>总是感觉一天什么都还没有做，时间就溜走了。分享一个我对于时间利用方式的理解，即碎片事情用碎片时间，完整事情用成块时间。怎么理解呢?我们日常有很多的碎片事情，如查邮件、刷微博、看微信等，这样的事情就可以利用碎片时间来做，例如上厕所、等公交、坐地铁等;例如完成产品某一功能便是完整事情，需要利用成块的非打扰时间来完成，这样才会将时间利用好。&lt;/p>&lt;p>3. 对自己负责&lt;/p>&lt;p>不论是提升工作效率，还是学习新的技能，都是在给自己积累经验和知识，在进行工作输出时，需要对自己所完成的内容进行负责，使其达到最好的状态和输出标准，这一切的努力都是在对自己负责。&lt;/p>&lt;p>4. 有效努力工作&lt;/p>&lt;p>加班是程序员跑不掉的话题，需要思考的是，在自己的工作内容里面，完成时到底用了多少有效时间，千万不要只是看上去很努力，做了很多无用功或是浪费了时间。当然，如果你公司文化是由加班多少来决定晋升和绩效的，要么玩这个游戏，要么离开这样的公司。&lt;/p>&lt;p>￼&lt;/p></description></item><item><title>Java面试经验，兼谈互联网公司后端面试经验</title><link>https://pangyd.com/post/98-java/</link><pubDate>Sun, 10 Sep 2017 19:47:01 +0800</pubDate><guid>https://pangyd.com/post/98-java/</guid><description>&lt;p>应聘相关&lt;/p>&lt;p>声明：&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>程序员相关的哈&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>万事无定论，比如说，就算你小学毕业，但是java基础却扎实到变态，我相信open的公司还是会给你机会的。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>心态很重要，虽然日常的心态不容易控制，面试那俩小时的心态，只要你想，就能控制。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>1、先来一份前辈的劝戒&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>坚持三年 ，不管在哪干，有一个好的平台，坚持三年以上才能出效果。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>如果跳的话，新公司需要稳定，最少过了B轮融资，，五万比一是创业型公司的失败率&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>不要着急，不要比较为了5000块的工资差价跳，不值得跳，从一万到三万，并且有一个好的平台的话，才值得跳。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>长期的看普华挺好的，从平台上讲，除了BAT华为，基本没有更好的&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>每天要多投些简历，每天投个几十份，别着急，多面面。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>2、再来一份傲骄的互联网公司的不收标准&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>符合以下条件的不要&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>二本以下，特别是学校名XXX学院&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>应届或者未毕业&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>在职并且不打算换工作&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>目标非北京&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>纯 windows / asp / c# / c sharp / .net / dot net&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>纯嵌入式&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>纯移动端 android / iOS&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>特别底层，比如操作系统内核裁剪&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>非计算机专业，计算机工作经验在一年以下&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>最近的项目，空白超过半年，比如现在8月份，项目经历只写到2月&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>87 年以前，除非背景特别牛&lt;/p></description></item><item><title>python爬虫——写出最简单的网页爬虫</title><link>https://pangyd.com/post/97-python/</link><pubDate>Sat, 09 Sep 2017 17:08:42 +0800</pubDate><guid>https://pangyd.com/post/97-python/</guid><description>&lt;section data-tools="135编辑器" data-id="89974" style="text-align: justify">&lt;section data-id="us538844">&lt;section>&lt;p>&lt;span class="bannerfix-wrapper" style="text-align: center">&lt;img data-s="300,640" data-type="jpeg" data-src="//qqpublic.qpic.cn/qq_public/0/0-2599578271-A1CD3C3D44AED332B9085FFD7BA070AD/0?fmt=jpg&amp;size=31&amp;rs=23-21&amp;h=427&amp;w=640&amp;ppv=1" data-ratio="0.66640625" data-w="1280" src="https://pangyd.com/uploads/2017/09/1b8214ac44494614.jpg" data-fail="0" data-ueid="20895" width="640" height="auto" data-width="640" data-height="427" data-org="https://mmbiz.qpic.cn/mmbiz_jpg/Mzws9oBx0P7kQpiaL4oQG7TZxbZ6hwFdlbmh5WVswicJbvugib0w0ujibUqXjvUgFuUSme9lNFeDeiaVoric6jSpvmGA/640?wx_fmt=jpeg&amp;wxfrom=5&amp;wx_lazy=1" data-lazy="0">&lt;/span>&lt;/p>&lt;/section>&lt;/section>&lt;/section>&lt;section data-id="us538844" style="text-align: justify">&lt;section>&lt;section>&lt;p>&lt;span>在我们日常上网浏览网页的时候，经常会看到一些好看的图片，我们就希望把这些图片保存下载，或者用户用来做桌面壁纸，或者用来做设计的素材。&lt;/span>&lt;span>我们可以通过&lt;/span>&lt;span>python&amp;nbsp;&lt;/span>&lt;span>来实现这样一个简单的爬虫功能，把我们想要的代码爬取到本地。下面就看看如何使用&lt;/span>&lt;span>python&lt;/span>&lt;span>来实现这样一个功能。&lt;/span>&lt;/p>&lt;/section>&lt;section data-width="100%">&lt;section>&lt;img data-src="//qqpublic.qpic.cn/qq_public/0/0-2516127415-94DD69FAB0632899CD9E62C400ADDFE6/0?fmt=png&amp;size=1&amp;rs=1-0&amp;h=37&amp;w=43&amp;ppv=1" data-ratio="0.8604651162790697" data-w="43" data-type="png" src="https://pangyd.com/uploads/2017/09/1b8214ac44494614.jpg" data-fail="0" data-ueid="592180" width="43" height="auto" data-width="43" data-height="37" data-org="https://mmbiz.qpic.cn/mmbiz_png/Mzws9oBx0P7kQpiaL4oQG7TZxbZ6hwFdlSWdbiaWc3zB05Dc3TN73GB0wFsJZ2xN6V1BlNytSzCqpkOSErJWEKRQ/0.png?wxfrom=5&amp;wx_lazy=1" data-lazy="0">&lt;/section>&lt;/section>&lt;/section>&lt;/section>&lt;section data-id="us538906" style="text-align: justify">&lt;section>&lt;section data-width="100%">&lt;section data-brushtype="text">&lt;span>&lt;strong>开发工具&lt;/strong>&lt;/span>&lt;/section>&lt;/section>&lt;/section>&lt;/section>&lt;p style="text-align: justify">&lt;span>笔者使用的工具是sublimetext3，它的短小精悍（可能男人们都不喜欢这个词）使我十分着迷。推荐大家使用，当然如果你的电脑配置不错，pycharm可能更加适合你。&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>sublime text3搭建python开发环境推荐查看此博客：&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>[sublime搭建python开发环境]&lt;/span>&lt;span>[https://www.cnblogs.com/codefish/p/4806849.&lt;/span>&lt;/p>&lt;section data-id="us538906" style="text-align: justify">&lt;section>&lt;section data-width="100%">&lt;section data-brushtype="text">&lt;span>&lt;strong>爬虫介绍&lt;/strong>&lt;/span>&lt;/section>&lt;/section>&lt;/section>&lt;/section>&lt;p style="text-align: justify">&lt;span>&lt;span>爬虫顾名思义，就是像虫子一样，爬在&lt;/span>Internet&lt;span>这张大网上。如此，我们便可以获取自己想要的东西。&lt;/span>&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>&lt;span>既然要爬在&lt;/span>Internet&lt;span>上，那么我们就需要了解&lt;/span>URL&lt;span>，法号&lt;/span>“&lt;span>统一资源定位器&lt;/span>”&lt;span>，小名&lt;/span>“&lt;span>链接&lt;/span>”&lt;span>。其结构主要由三部分组成：&lt;/span>&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>&lt;span>（&lt;/span>1&lt;span>）协议：如我们在网址中常见的&lt;/span>HTTP&lt;span>协议。&lt;/span>&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>&lt;span>（&lt;/span>2&lt;span>）域名或者&lt;/span>IP&lt;span>地址：域名，如：&lt;/span>www.baidu.com&lt;span>，&lt;/span>IP&lt;span>地址，即将域名解析后对应的&lt;/span>IP&lt;span>。&lt;/span>&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>&lt;span>（&lt;/span>3&lt;span>）路径：即目录或者文件等。&lt;/span>&lt;/span>&lt;/p>&lt;section data-id="us538906" style="text-align: justify">&lt;section>&lt;section data-width="100%">&lt;section data-brushtype="text">&lt;strong>urllib开发最简单的爬虫&lt;/strong>&lt;/section>&lt;/section>&lt;/section>&lt;/section>&lt;h2 style="text-align: justify">&lt;strong>（1）urllib简介&lt;/strong>&lt;/h2>&lt;p style="text-align: justify">&lt;span class="bannerfix-wrapper" style="text-align: center">&lt;img data-s="300,640" data-type="png" data-src="//qqpublic.qpic.cn/qq_public/0/0-2934665086-C4DD3D1B4A848A0F5D9739358CE38612/0?fmt=png&amp;size=12&amp;rs=9-8&amp;h=202&amp;w=837&amp;ppv=1" data-ratio="0.24133811230585425" data-w="837" src="https://pangyd.com/uploads/2017/09/1b8214ac44494614.jpg" data-fail="0" data-ueid="266081" width="837" height="auto" data-width="837" data-height="202" data-org="https://mmbiz.qpic.cn/mmbiz_png/Mzws9oBx0P7kQpiaL4oQG7TZxbZ6hwFdlbAnCoicvLvF2aLKfpCqp6NaztGRzkTQvN6LRN0av2u6XVBjA2N1b7LA/0.png?wxfrom=5&amp;wx_lazy=1" data-lazy="0">&lt;/span>&lt;/p></description></item><item><title>Java集合类</title><link>https://pangyd.com/post/96-java/</link><pubDate>Fri, 08 Sep 2017 21:07:49 +0800</pubDate><guid>https://pangyd.com/post/96-java/</guid><description>&lt;p>看了一些所谓大&lt;a target="_self" href="https://pangyd.com/contribute/">公司&lt;/a>的JAVA面试问题，发现对于JAVA集合类的使用都比较看重似的，而自己在这方面还真的是所真甚少，抽空也学习学习吧。&lt;/p>&lt;p>&lt;/p>&lt;p>java.util包中包含了一系列重要的集合类，而对于集合类，主要需要掌握的就是它的内部结构，以及遍历集合的迭代模式。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>&lt;span>接口：Collection&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>Collection是最基本的集合接口，一个Collection代表一组Object，即Collection的元素（Elements）。一些Collection允许相同的元素而另一些不行。一些能排序而另一些不行。Java SDK不提供直接继承自Collection的类，Java SDK提供的类都是继承自Collection的“子接口”如List和Set。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>所有实现Collection接口的类都必须提供两个标准的构造函数：无参数的构造函数用于创建一个空的Collection，有一个Collection参数的构造函数用于创建一个新的Collection，这个新的Collection与传入的Collection有相同的元素。后一个构造函数允许用户复制一个Collection。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>主要的一个接口方法：boolean add(Ojbect c)&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>虽然返回的是boolean，但不是表示添加成功与否，这个返回值表示的意义是add()执行后，集合的内容是否改变了（就是元素的数量、位置等有无变化）。类似的addAll，remove，removeAll，remainAll也是一样的。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>&lt;span>用Iterator模式实现遍历集合&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>Collection有一个重要的方法：iterator()，返回一个Iterator（迭代器），用于遍历集合的所有元素。Iterator模式可以把访问逻辑从不同的集合类中抽象出来，从而避免向客户端暴露集合的内部结构。典型的用法如下：&lt;/p>&lt;blockquote>&lt;p>Iterator it = collection.iterator(); // 获得一个迭代器&lt;/p>&lt;p>while(it.hasNext()) {&lt;/p>&lt;p>Object obj = it.next(); // 得到下一个元素&lt;/p>&lt;p>}&lt;/p>&lt;/blockquote>&lt;p>不需要维护遍历集合的“指针”，所有的内部状态都由Iterator来维护，而这个Iterator由集合类通过工厂方法生成。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>每一种集合类返回的Iterator具体类型可能不同，但它们都实现了Iterator接口，因此，我们不需要关心到底是哪种Iterator，它只需要获得这个Iterator接口即可，这就是接口的好处，面向对象的威力。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>要确保遍历过程顺利完成，必须保证遍历过程中不更改集合的内容（Iterator的remove()方法除外），所以，确保遍历可靠的原则是：只在一个线程中使用这个集合，或者在多线程中对遍历代码进行同步。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>由Collection接口派生的两个接口是List和Set。 　&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>&lt;span>List接口&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>List是有序的Collection，使用此接口能够精确的控制每个元素插入的&lt;a target="_self" href="https://pangyd.com/contribute/">位置&lt;/a>。用户能够使用索引（元素在List中的位置，类似于数组下标）来访问List中的元素，这类似于Java的数组。和下面要提到的Set不同，List允许有相同的元素。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>除了具有Collection接口必备的iterator()方法外，List还提供一个listIterator()方法，返回一个ListIterator接口，和标准的Iterator接口相比，ListIterator多了一些add()之类的方法，允许添加，删除，设定元素，还能向前或向后遍历。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>实现List接口的常用类有LinkedList，ArrayList，Vector和Stack。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>&lt;span>LinkedList类&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>LinkedList实现了List接口，允许null元素。此外LinkedList提供额外的get，remove，insert方法在LinkedList的首部或尾部。这些操作使LinkedList可被用作堆栈（stack），队列（queue）或双向队列（deque）。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>注意LinkedList没有同步方法。如果多个线程同时访问一个List，则必须自己实现访问同步。一种解决方法是在创建List时构造一个同步的List：List list = Collections.synchronizedList(new LinkedList(...));&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>&lt;span>ArrayList类&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>ArrayList实现了可变大小的数组。它允许所有元素，包括null。ArrayList没有同步。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>size，isEmpty，get，set方法运行时间为常数。但是add方法开销为分摊的常数，添加n个元素需要O(n)的时间。其他的方法运行时间为线性。&lt;/p>&lt;p>每个ArrayList实例都有一个容量（Capacity），即用于存储元素的数组的大小。这个容量可随着不断添加新元素而自动增加，但是增长算法并没有定义。当需要插入大量元素时，在插入前可以调用ensureCapacity方法来增加ArrayList的容量以提高插入效率。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>和LinkedList一样，ArrayList也是非同步的（unsynchronized）。&lt;/p>&lt;p>&lt;br>&lt;/p></description></item><item><title>江北腾飞的水城</title><link>https://pangyd.com/post/95/</link><pubDate>Thu, 07 Sep 2017 20:19:12 +0800</pubDate><guid>https://pangyd.com/post/95/</guid><description>&lt;p style="text-align: left">&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 腾飞的江北水城&lt;/p>&lt;p>&amp;nbsp; “人人都说,沂蒙四个好地方。”沂蒙三小调的歌词唱出了临沂人的骄傲和自豪。故称琅琊的临沂,市委领的英名的带领下。从贫穷落后走向了富裕.美丽.和谐。依托丰富的水资源，建成了气势宏大的滨河大道，让临沂从商城变成了让人惊叹的大&lt;a target="_self" href="https://pangyd.com/">美文&lt;/a>明城市。&lt;/p>&lt;p>&amp;nbsp; &amp;nbsp;作为革命老区的临沂，在历史战争中涌现出无数英雄，沂蒙人用清清的沂河水哺育了无数的英雄豪杰，让不屈的沂蒙人变得更加坚强，更加无私，旧有沂蒙六姐妹，用沂蒙精神记载了不朽的历史；今有不甘落后的沂蒙人，向应党的号召，改革开放之路，唱着春天的故事，改革富起来。富起来的沂蒙人发挥自己的聪明才智，充分利用现有的丰富的水资源，建成贯通南北的滨河大道，让名不见经传的地级市变成了全国文明.卫生城市。&lt;/p>&lt;p>&amp;nbsp; &amp;nbsp;在水上大做&lt;a target="_blank" href="https://pangyd.com/">文章&lt;/a>的临沂，建成了与日照沙滩相媲美的阳光沙滩，闲暇的人们在享受着愉快的幸福生活；风景独秀的滨河风景让我们留连忘返，喜欢垂钓的在风景如画的岸边尽显风采；爱好游泳的在碧波荡漾，波光如镜的水中自由的游动，热恋中的青年在忘情的说笑；天真无邪的孩子在岸边的游戏场中尽情的玩耍；打球的，下棋的，散步的……富裕起来的沂蒙人正沿着幸福的生活中，他们在享受着党的温暖，正走在小康的幸福大道上。生长于斯得人民能不热爱这方热土吗？&lt;/p>&lt;p>&amp;nbsp; &amp;nbsp;从2002年到现在,沂蒙老区处处高楼林立，路路畅通。正在崛起的南坊新区，座座高楼拔地而起，街道宽敞，绿化一流，风景秀丽。大美临沂。让世人惊叹。我高声的赞美现代化的临沂，我热爱腾飞的江北水城，我要努力刻苦学习，用知识武装自己的头脑，将要用所学的知识把临沂建设得更富裕，更美丽，更和谐。&lt;/p>&lt;p>&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p>&lt;p style="text-align: center">作者:李洋&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p style="text-align: right">&lt;b>纯手打不宜 希望能尊重原创&lt;/b>&lt;/p>&lt;p style="text-align: right">&lt;b>如转载请注明以下文字 否为侵权&lt;br>作者博客：&lt;a target="_blank" href="https://pangyd.com/">pangyd.com&lt;/a>&lt;br>作者博客接受文章来稿：详情点击&lt;/b>&lt;/p></description></item><item><title>网站改版301重定向与快速恢复收录解决方法</title><link>https://pangyd.com/post/94-301/</link><pubDate>Wed, 06 Sep 2017 19:20:43 +0800</pubDate><guid>https://pangyd.com/post/94-301/</guid><description>&lt;p>今天终于趋于稳定，起码博客在百度重新收录让我感到一丝欣慰。谷歌和360在昨天就已经恢复了收录。但目前百度搜索的流量仍是本站最多的流量来源，所以直到百度有了收录我才松了口气。对于看重SEO的人，对收录重视程度不必多说。&lt;div>&lt;br>&lt;/div>&lt;div>　　本次恢复收录统计：百度：2天，谷歌：1天，360 ：1天。&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>　　当然只是有了部分收录，并不是所有页面完全收录转移了。估计要等到所有页面转移，权重转移可能需要2个星期甚至一个月。&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>　　自我感觉还不错，因为我之前百度了一下前辈们是怎么处理这种事情的，发现有的人一个月还没有被收录。所以我感觉自己真的是很幸运。大家这里不用怀疑我新站的收录会不会是百度的正常收录。因为我可以完全肯定是我自己的功劳。下面我会把自己所做的方法完全分享出来，给大家一个借鉴。&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>　　1，&lt;a target="_blank" href="https://pangyd.com/">网站&lt;/a>301重定向。虽然很多朋友都知道什么是301了，但我还是系统的说一下。&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>　　&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div> &lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>　　页面永久性移走(301重定向)是一种非常重要的“自动转向”技术。网址重定向最为可行的一种办法。当用户或搜索引擎向网站服务 器发出浏览请求时，服务器返回的HTTP数据流中头信息(header)中的状态码的一种，表示本网页永久性转移到另一个地址”。&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>　　这样就明白了，简单看来就是显性的URL转发。实际意义就是告诉搜索引擎这个页面已经永久的被转移到另一个页面了。既然知道了这个301的意义，那如何做301重定向呢?&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>　　1)，可以在域名解析端设置301重定向。现在一般的域名解析服务商已经提供301重定向的功能，如DNSPOD，但是需要域名转入1个月以后，而且需要审核。&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>　　2)，服务器端301重定向，现在大部分虚拟主机管理面板都提供了这一选项。比如我用的DA。或者一些国内的面板都有。(因为面板不同，具体方法可以留言，我帮助你。或者自行百度。这里就不在叙述。)当然如果你是VPS用户或者服务器用户因为面板自己安装可能就没有这一功能，那么你可以使用方法1或者3。&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>　　IIS重定向的方法：Internet信息服务管理器 -&amp;gt; 虚拟目录 -&amp;gt; 重定向到URL，输入需要转向的目标URL，并选择&amp;quot;资源的永久重定向&amp;quot;。&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>　　3)，代码重定向，这个就是比较通用的了，用代码的方式实现301重定向&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>　　1.301重定向之ASP&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>　　2、301重定向之PHP&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>　　Header( &amp;ldquo;HTTP/1.1 301 Moved Permanently&amp;rdquo; ) ;&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>　　Header( &amp;ldquo;Location: https://www.&lt;em>&lt;strong>.com&amp;rdquo; );&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>　　?&amp;gt;&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>　　3、301重定向之NET&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>　　还有的虚拟主机自带了配置文件，使用方法如下。&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>　　把下面一段代码 保存为 httpd.ini 放到web里。网址换成自己。实现301跳转.&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>　　[ISAPI_Rewrite]&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>　　CacheClockRate 3600&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>　　RepeatLimit 32&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>　　RewriteCond Host: ^&lt;/strong>&lt;/em>.com&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>　　RewriteRule (.&lt;em>) https://www.&lt;/em>&lt;em>&lt;em>.com$1 [RP]&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>　　下面是.htaccess的代码&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>　　RewriteEngine On&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>　　RewriteCond %{http_host} ^ycyskycom [NC]&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>　　RewriteRule ^(.&lt;/em>)$ https://www.&lt;/em>**.com/$1 [R=301,L]&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>　　2，既然做好了网页重定向，那么下一步就是去百度站长平台提交改版规则。&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>　　以下是百度站长平台的改版规则说明及其我网站改版提交的规则截图&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>　　&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div> &lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>　　改版范围说明域名改版：会将此站点其子站点下所有的页面进行改版处理。比如当前站点为 &lt;a href="https://baidu.com/">https://baidu.com/&lt;/a>，域名范围的改版会将 &lt;a href="https://baidu.com/">https://baidu.com/&lt;/a>，http://wenku.baidu.com/，http://tieba.baidu.com/ 等站点的所有页面一并做改版处理。目录改版：支持当前站点的目录和子站点的目录，把此目录下的URL做改版处理。比如当前站点是 &lt;a href="https://baidu.com/">https://baidu.com/&lt;/a>，改版范围是 &lt;a href="https://wenku.baidu.com/ac/">https://wenku.baidu.com/ac/&lt;/a>，则会将 &lt;a href="https://wenku.baidu.com/ac/1.html">https://wenku.baidu.com/ac/1.html&lt;/a>，http://wenku.baidu.com/ac/2.html 等URL做改版处理。&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>　　规则提交后，一般48小时内会反馈预计处理时间，每天更新一次处理进度。期间您可以通过以下方法来查看改版处理情况：关注新网站的抓取异常情况，短期内适当提升抓取压力帮助新网站更快抓取;关注新网站的索引量波动，关注网站改版工具显示的已替换链接条数;同时对旧网站的域还需保留一段时间，直到新网站在百度索引和展现效果佳。&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>　　注：在站长平台提交改版规则很重要，如果提交的话，可能收录很快恢复，像我的两天就有了新的收录，如果收录是新站的话，是不可能的，即便有收录，也不会先收录内容页而不收录首页。所以这一部很重要，但需要注意的是，提交之前务必做好301重定向。&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>　　3，向百度提供sitemap，也就是网站结构化地图。因为每个网站系统不同的原因构架也不同，这里也不好说什么，但是百度站长平台提供了Discuz!和Wordpress结构化的插件，可以简易的提交网站sitemap。但也会相应的增加服务器负担。&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>　　注：平常最好也使用，不必301重定向时才使用。(服务器负担问题这里不计算，请自行测试。)&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>　　4，网站链接&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>　　这个就不必说太多了，因为平时大家可能做的最多的就是外链与友链。写在301重定向这里的意思就是希望大家尽快把友情链接转移到新域名处，增加新域名的权重，而外链就要重新去发喽。&lt;/div>&lt;div>&lt;br>&lt;/div>&lt;div>　　写到这里，本篇&lt;a target="_blank" href="https://pangyd.com/">文章&lt;/a>就结束了，因本人才疏学浅，写此文章也纯属一时兴起，如有不正确的地方希望予以包含和指正。感谢www.ycysky.com站长投稿!&lt;/div>&lt;/p></description></item><item><title>个人失败的网站运营经历，三年一分钱没赚到</title><link>https://pangyd.com/post/93/</link><pubDate>Tue, 05 Sep 2017 18:10:27 +0800</pubDate><guid>https://pangyd.com/post/93/</guid><description>&lt;p style="text-align: justify">如果是三年前的自己，根本就不会想过三年后会是这个样子——运营三年一分钱都没有赚到。服务器成本、域名成本等硬性成本全部都是自讨腰包。其他人工推广维护根本就无法计算。&lt;/p>&lt;p style="text-align: justify">今天，三年前的续费即将过去到期，开始思考着自己是该继续续费还是放弃。&lt;/p>&lt;p style="text-align: justify">叹屌丝逆袭多么的艰难。一开始想的是多么的美好。“建立一个内容丰富的网站，有图片、文字、聊天、交友。运营一段时间内流量上来了就挂谷歌adsense赚取点费用维持服务器成本。后期通过这个网站盈利，想着日赚XXX的美梦。”但是没有想过结局跟网上吹的那种日赚XXX是多么的天壤之别。&lt;/p>&lt;p style="text-align: center">&lt;img alt="个人失败的网站运营经历，三年一分钱没赚到 好文分享" title="个人失败的网站运营经历，三年一分钱没赚到 好文分享" src="https://pangyd.com/uploads/2017/09/d5731b7a2fec55d4.jpg" width="590" height="417">&lt;/p>&lt;p style="text-align: center">（博文配图，图片与作者本文无关）&lt;/p>&lt;p style="text-align: justify">&lt;strong>第一年：&lt;/strong>&lt;/p>&lt;p style="text-align: justify">挂&lt;a href="https://lusongsong.com/info/post/310.html" target="_blank">adsense&lt;/a>，半年多了还不到100人民币，点击单价越来越低而且要多低就有多低，基本上等于免费挂谷歌的广告。虽然网站流量每天在1K,PV在2K左右，但对于盈利仍旧是无计可施。&lt;a href="https://baidu.com" target="_blank" class="keywordlink">百度&lt;/a>收录有谷歌收录访客有流量但是根本就赚不到钱。看到这样的情况，满腔热情有点被泼冷水的感觉，但是还是坚持，心里想着是网站挂着又没事。&lt;/p>&lt;p style="text-align: justify">&lt;strong>第二年：&lt;/strong>&lt;/p>&lt;p style="text-align: justify">很悲催，谷歌adsense不给任何理由就把我的网站域名给封了。之后我想过去挂百度联盟的广告，很可惜，没有备案网站是放不了百度的联盟广告的。还有其他的联盟比如阿里妈妈，根本就不用去挂的。网站每天没有几千几万流量，挂几十年收入都是0!剩下的其他一些杂乱的广告联盟商，不想去浪费时间，看到他们的广告感觉很低俗、如果网站上面挂了那样的广告给人的感觉就是一个s情h站!都是些卖w哥、壮阳、或者luo聊、同城交友(那种)、游戏弹窗，挂马的广告。如果放这样的广告到自己的网站上，只能是饮鸩止渴。很悲催的，服务器费用仍旧是自己掏腰包。而且已经一种不管他的状态。&lt;/p>&lt;p style="text-align: justify">&lt;strong>第三年：&lt;/strong>&lt;/p>&lt;p style="text-align: justify">很多人都说如果一个网站已经运营了超过2年还是不盈利，那么这个网站可以关闭了。现在想起来，觉得确实是的，2年的时间，已经不是新站了。但是仍旧不是盈利状态，只能说明运营不善。第三年里面很心灰意懒，不想去给网站加什么内容，只是定期备份，检查网站是否可以正常使用是否可以正常运行。访问流量还是那样差，每天才2K IP左右。雪上加霜的是在2012年六七月份的时候，百度k站了，流量直线下降90%。后来虽然收录上回升了一半，有1万多。但是每天来自百度的流量始终都是0，切切实实始终都是0。没有流量，更别提盈利，让自己更觉得心灰意懒。&lt;/p>&lt;p style="text-align: justify">&lt;strong>第四年：今年现在2013。&lt;/strong>&lt;/p>&lt;p style="text-align: justify">静下心来思考，开始反思。想到了自己为什么要做这个网站，觉得有点可笑，一开始想着通过运营网站赚钱，结果却是一直都是自掏腰包赔本。自己该继续运营下去还是直接放弃?不由得想到了网站的最终结果：收点小钱而已，不用自己掏腰包去垫付服务器的成本费和域名的注册费。&lt;/p>&lt;p style="text-align: justify">&lt;strong>自己该继续坚持下去吗?&lt;/strong>&lt;/p>&lt;p style="text-align: justify">跟别人交流了很多次，把网站给了很多人看。&lt;/p>&lt;p style="text-align: justify">很多人打开一瞪眼就说网站太丑了，一个图片都没有，一个动画都没有，不想继续访问下去，想直接关闭。有的人说访问速度太慢了。其实是因为我网站没有beian，只能放在国外，虽然已经算是最快的服务器了，但是访问速度还是很慢。没有办法，自己网站一直都是不盈利不赚钱，哪有那么多钱去升级服务器买好的服务器?也给了一些SEO人士看，都说出来的是网站没有外链，很少。基本上没有在外面宣传推广过一样。因为自己没有那么多精力去推广，只能三天打鱼两天晒网。&lt;/p>&lt;p style="text-align: justify">网站运营的第四年，也许自己已经明白了这个网站为什么一直都是这么没有起色，没有流量也没有收益。看到很多域名注册不到1年的网站流量、收录都异常火爆、权重非常高，让自己觉得奇怪，自己一开始认定的域名越老越权重高，而自己的网站已经运营了三四年了，百度权重还是0、谷歌pr也从原先的2降到了0。&lt;/p>&lt;p style="text-align: justify">回想自己这三年来的付出，经常熬夜通宵达旦的修改网站程序源码，基本上已经把网站源码改得地覆天翻。经常为了调节一个细小的代码优化而废寝忘食、甚至一整天坐在电脑前一动不动，没时间上厕所没时间吃饭睡觉洗漱。等于就是在自己做一个PHP CMS系统。但是网站做好之后就坐等搜索引擎收录，靠天吃饭一样，搜索引擎那天心情不好自己就一个字都别想了。发现很多网站他们的程序根本从来都不改动一下，直接CMS下载来加内容，域名也注册不到1、2年，但是流量收录PR权重非常高、人气非常火爆。对比之下，自己显得多么相形见绌，开始深刻的怀疑一开始自己信定的域名越老人气越旺的谬论。&lt;/p>&lt;p style="text-align: justify">打开自己的网站，发现网站界面确实是那么的丑陋，因为自己不会PS不会图片处理，也不会仿站，所以网站界面一直都是那么的丑陋，以前给别人看自己的网站，也许这是大部分写代码的人的不足之处，不会设计界面，不会美工。&lt;/p>&lt;p style="text-align: justify">&lt;strong>思考、总结了很多，明白了自己失败的所在：&lt;/strong>&lt;/p>&lt;p style="text-align: justify">一网站界面太丑陋，不会美工设计、logo都是非常难看的。&lt;/p>&lt;p style="text-align: justify">二从来没有推广宣传过只是坐等搜索引擎收录，靠天吃饭。&lt;/p>&lt;p style="text-align: justify">三网站服务器太差，舍不得升级好一点的。死做站，只会改程序而其他的根本就从不顾及。&lt;/p>&lt;p style="text-align: justify">四从来没主动去寻找过广告商，日IP 2K其实挂一个其他的广告就可以满足服务器费用了，但是没有去寻找也丢失了盈利的欲望。&lt;/p>&lt;p style="text-align: justify">网站已运营三年，败在了方向上。很少推广……唯一做得最多的就是程序，死改、死改!完全的倾向与技术性。死改程序死改程序，死读书一样。&lt;/p>&lt;p style="text-align: justify">&lt;strong>但是我该继续下去吗?&lt;/strong>&lt;/p>&lt;p style="text-align: justify">很多科学的统计，中国的个人站长至少80%都是不盈利，任何费用都是自己出，其他人工的维护、推广宣传人力精力更不包含在内。另外10%是勉强可以赚得点服务器费用和域名费用。只有剩下10%不到的才收入大于支出，但是剩余不一定抵得上他的其他付出——时间精力人力推广。&lt;/p>&lt;p style="text-align: justify">同时也想到了自己网站，主题主题、发展模式要被复制太容易了。个人站长真的力量太薄弱，有什么变动，就立即会夭折。一切都是迷路。感言：个人建站小打小闹还可以但是真的想通过建个网站来运营就逆袭，只能是想的太离谱。&lt;/p>&lt;p style="text-align: justify">本文作者：&lt;a href="https://www.im286.com/thread-11086188-1-1.html" target="_blank" rel="nofollow">foho&lt;/a>&lt;/p>&lt;p style="text-align: right">来源：&lt;a target="_self" href="https://pangyd.com/">庞玉栋博客&lt;/a> 欢迎分享&lt;/p></description></item><item><title>my sql 数据库连接Java库</title><link>https://pangyd.com/post/11-my-sql-java/</link><pubDate>Tue, 05 Sep 2017 09:09:51 +0800</pubDate><guid>https://pangyd.com/post/11-my-sql-java/</guid><description>&lt;div style="margin:1.5rem 0;padding:1rem;background:var(--bg-elev);border:1px solid var(--line);border-radius:10px;display:flex;flex-wrap:wrap;gap:.75rem;align-items:center">
 &lt;span class="mono" style="font-size:.8rem;color:var(--fg-muted)">附件&lt;/span>
 &lt;a href="https://pangyd.com/downloads/94c4eb6185ec2e8e_6610671affa295ec657487ae20a755dd.jar" download style="font-weight:600">mysql-connector-java-5.0.8-bin.jar&lt;/a>
&lt;/div></description></item><item><title>庞玉栋:浅谈seo优化对于网站建设的重要性</title><link>https://pangyd.com/post/91-seo/</link><pubDate>Mon, 04 Sep 2017 19:09:42 +0800</pubDate><guid>https://pangyd.com/post/91-seo/</guid><description>&lt;p>根据最近做SEO优化经验而写 &amp;nbsp;写的也都是我的方法 大神勿喷&lt;/p>&lt;p>SEO：英文Search Engine Optimization缩写而来， 中文意译为搜索引擎优化&amp;nbsp;&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>如果你连个网站都没有那就点这里：&lt;a target="_self" href="https://pangyd.com/post/90/">&lt;b>如何拥有一个属于自己的网站&lt;/b>&lt;/a>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>现在的中国搜索引擎 百度是无可置疑的老大 &amp;nbsp;在以前 是谷歌 百度 和soso平分天下 只从谷歌退出江湖 &amp;nbsp;百度就成了第一 soso自然也就排名第二 那为什么现在看不到soso的存在了呢。就是因为soso被搜狗并购 然后360搜索接踵而来 &amp;nbsp;现在最主要的搜索引擎也就成了 百度 搜狗 360搜索&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>一个网站的建设除了把网站搭建好 你还要让搜索引擎喜欢你 &amp;nbsp;要不然你的网站就是一个死站 &amp;nbsp;基本上没有什么人访问&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>那怎么样才能让搜索引擎喜欢你呢 &amp;nbsp;&lt;/p>&lt;p>简洁的站点结构 代码结构良好 层次分明 这样更容易吸引搜索引擎的爬虫光临 收录你的网站&lt;/p>&lt;p>第一就是你网页的内容 &amp;nbsp;爬虫会先爬取你meta标签里的内容 &amp;nbsp;所以网页的内容一定要和关键字想匹配还有就是关键词的密度一定要在全文占比的2%左右 &amp;nbsp;可以用站长工具的密度查询工具&lt;/p>&lt;p>第二是锚链接 &amp;nbsp;锚链接就是你网页内容中文本所链接超链接 &amp;nbsp;爬虫更喜欢爬这种页面 &amp;nbsp;但是锚链接一定要跟文本内容相匹配 &amp;nbsp;再之就是不要过过 &amp;nbsp;一个页面的锚链接在两个左右就可以&lt;/p>&lt;p>第三是图片的alt标签一定要写上 &amp;nbsp;可以在上面加点关键词 以增加网页关键词的密度 &amp;nbsp;一举两得 &amp;nbsp;&lt;/p>&lt;p>有一句话就是 &amp;nbsp;内容为皇 &amp;nbsp;外链为王 &amp;nbsp;&lt;/p>&lt;p>网页的内容为主要的 其次就是你域名在别的网站所在的数量 &amp;nbsp;建议多在各种博客和论坛多写点文章 &amp;nbsp;然后把超链接加到文本上 &amp;nbsp;这样会增加外链的数量 &amp;nbsp;还有就是选择权重和收录量比较高的网站 &amp;nbsp;这样怕虫子在爬网站的时候会查看你的超链接 &amp;nbsp;吸引爬虫更多的光临你的网站 &amp;nbsp;然后还有友链 就是友情链接 可以跟别的网站交换友情链接 &amp;nbsp;这也是seo优化的一部分 &amp;nbsp;&lt;/p></description></item><item><title>回望过去 展望未来-----李洋</title><link>https://pangyd.com/post/90/</link><pubDate>Sun, 03 Sep 2017 11:12:25 +0800</pubDate><guid>https://pangyd.com/post/90/</guid><description>&lt;p>经过了一个学年的我，没有太多的收获，只是一步一个脚印跟着老师向前走，没有太多的想法；经过一个暑期的放纵，发现自己落后，跟不上他们的节奏，整个暑假不知道干什么的，顿时迷失了方向，不知道何去何从；新学期伊始，顿时感觉到了压力，是从自己内心发出来的，也萌生了许多的想法。&lt;/p>&lt;p>去年的考试失利，不知道如何去面对，如何去表达；内心一直存在着种种疑惑，是实力问题还是有其他的原因······与本科失之交臂，从此踏上高职的征程。曾经父亲对我说过：“你不论去哪里上学，我都亲自送你”。结果来到了这里，我也没有太多的顾虑，不论高职还是本科，只要好好干，在哪里不一样。来到这里生活已经有一个年头了，按照老师讲授的课程，认认真真的学习，稳扎稳打，一步一个脚印，最终取得了不错的成绩，没有太多的压力。大学就是自我安排，自我控制，自我发展的过程，那时的我就是这样认为。没有自主学习的习惯，没有拓宽自己的知识面，没有阅读大量的书籍······导致了大量的时间白白的浪费，回想起来是真的感到可惜，是一个错误的选择。&lt;/p>&lt;p>新学期，新气象，新打算。俗话说：“世上无难事只怕有心人。”我这次要做好充足的准备，迎接新学期，努力在这一个学年里，有点小突破，有点小成就。大二我也不能松懈，把各个专业学好、学精、学透，为以后的发展打下夯实的基础。“车到山前必有路，柳暗花明又一村”，没有扎实的基础，用人单位怎么用你，给你一个项目，能否胜任？大学生是最廉价的劳动力；可以就业，而我毅然选择读书，只有读书能增长见识，提高自身能力，实现自我价值更近一步。这一年我需要做的事情有以下几点：学好专业知识，提高自身技能；加强词汇量的积累，多做阅读理解；数学深入探究，增强逻辑思维；增加阅读量，涉猎群书；这是我这个周期需要落实的。&lt;/p>&lt;p>1．&lt;span class="Apple-tab-span">	&lt;/span>学会进行时间的管理，对自己的行程合理的规划。&lt;/p>&lt;p>2．&lt;span class="Apple-tab-span">	&lt;/span>情绪的合理的控制，处理好人与人之间的关系。&lt;/p>&lt;p>3．&lt;span class="Apple-tab-span">	&lt;/span>改正自己的缺点，发挥自己的长项。&lt;/p>&lt;p>4．&lt;span class="Apple-tab-span">	&lt;/span>学业方面进行深入的研究和探索。&lt;/p>&lt;p>5．&lt;span class="Apple-tab-span">	&lt;/span>每天给自己充电。&lt;/p>&lt;p>&amp;nbsp; &amp;nbsp;我对我自己的现状不是很满意，要去克服，通过以后的努力，来成就辉煌的明天。&lt;/p>&lt;p style="text-align: right">&lt;b>纯手打不宜 &amp;nbsp; 希望能尊重原创&lt;/b>&lt;/p>&lt;p style="text-align: right">&lt;b>如转载请注明以下文字 否为侵权&lt;/b>&lt;/p>&lt;p style="text-align: right">&lt;b>文章博客：&lt;a target="_self" href="https://pangyd.com/">pangyd.com&lt;/a>&lt;/b>&lt;/p>&lt;p style="text-align: right">&lt;b>联系QQ：2633759084&lt;/b>&lt;/p></description></item><item><title>如何拥有一个属于自己的网站</title><link>https://pangyd.com/post/89/</link><pubDate>Sun, 03 Sep 2017 09:49:38 +0800</pubDate><guid>https://pangyd.com/post/89/</guid><description>&lt;p>&lt;b>&lt;i>前言&lt;/i>&lt;/b>&lt;/p>&lt;p>网站顾名思义就是网上的一个站点 &amp;nbsp;而你打开的页面就是一个站点上的一个一个文件。那就有人问了，我有一台可以上网的计算机可不可以当站点用呢？答案是肯定的 通俗点来讲就跟你平时串门一样 这家门开着你就可以进去 &amp;nbsp; 但是现在计算机日益发展强大 家家都是用路由器 而且网络运营商分给每台计算机的IP都不是固定的 一般都是动态分配的 所以大多数人你即使开启了你电脑的服务器 因为端口 和IP地址问题 &amp;nbsp;也是很麻烦的 &amp;nbsp;因为你电脑连的路由器 你电脑上的ip地址是内网地址也就是192.168.1.1这样的 &amp;nbsp;再说就是你电脑不是专业的服务器 不能满足一个服务器的基本需求 &amp;nbsp;。说了这么多 也就是自己的电脑当服务器是基本上不可取的！&lt;/p>&lt;p>那还有什么办法可以创建一个网站呢？&lt;/p>&lt;p>整体的步骤是：&lt;/p>&lt;p>1：选择服务器和虚拟空间&lt;/p>&lt;p>2：选择合适的域名&lt;/p>&lt;p>3：网站备案&lt;/p>&lt;p>4：上传网页文件&lt;/p>&lt;p>5：完成&lt;/p>&lt;p>&lt;b>&lt;i>1：选择服务器和虚拟空间&lt;/i>&lt;/b>&lt;/p>&lt;p>现在基本上中大型企业基本上都是有自己的服务器 &amp;nbsp;而小企业和个人一般都是采用第三方的虚拟主机和云服务器来进行建站 比如阿里云 腾讯云 百度云等 还有免费的网眼等 &amp;nbsp;我高三的时候用过网眼的免费空间搭建过聊天机器人 &amp;nbsp;心得就是：免费的就是不好用&lt;img src="https://pangyd.com/uploads/2017/08/44ddb3ea33fe01f7.gif" alt="[微笑]">&amp;nbsp; &amp;nbsp;现在好了 &amp;nbsp;什么免费的虚拟空间和云服务器都便宜了 &amp;nbsp;建站的人也多了 &amp;nbsp;。&lt;/p>&lt;p>我接下来主要是讲阿里云虚拟主机建站过程：&lt;/p>&lt;p>闲话少说 &amp;nbsp;现在阿里云有个活动就是新用户可以免费领取半年的云服务器（ps：基本上抢不到），也有个6元一年的虚拟主机活动 &amp;nbsp;建议有一些建站知识的可以买云服务器 &amp;nbsp;没有建站知识的那就买虚拟主机吧！毕竟你买了云服务器也不知道咋用，那些连虚拟主机也不会用的就自己问度娘把，实在不会就点这里：&lt;a target="_blank" href="https://wpa.qq.com/msgrd?v=3&amp;uin=2500918234&amp;site=qq&amp;menu=yes">热心的博主&lt;/a>（ps：&lt;a target="_self" href="https://wanwang.aliyun.com/hosting/free?spm=5176.8112568.483655.5.tuqHEt">这里放上阿里云虚拟主机的6元活动&lt;/a>）&amp;nbsp;&lt;/p>&lt;p>&lt;b>&lt;i>2：选择合适的域名&lt;/i>&lt;/b>&lt;/p>&lt;p>接下来，买完主机了 你就需要你一个自己域名（ps：这里放上：&lt;a target="_blank" href="https://pangyd.com/post/5/">个人博客应该选怎样的域名&lt;/a>）&amp;nbsp;&lt;/p>&lt;p>&lt;b>&lt;i>3：网站备案&lt;/i>&lt;/b>&lt;/p>&lt;p>接下来就是域名备案：&lt;/p>&lt;p>&lt;img src="https://pangyd.com/uploads/2017/09/515b164f020bb08b.png" alt="UXCL~[%`GY]${~@(IB7XUHA.png">&lt;br>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>2&lt;/p>&lt;p>&lt;img src="https://pangyd.com/uploads/2017/09/a08638e72abe25eb.png" alt="@%(LF{Z]C7$$P8$@6{AE`TC.png">&lt;br>&lt;/p>&lt;p>&lt;img src="https://pangyd.com/uploads/2017/09/0f5a016588300e20.png" alt="YBK}1NQRU8MVHIS(B94I]Y8.png">&lt;br>&lt;/p>&lt;p>&lt;img src="https://pangyd.com/uploads/2017/09/5493d5199098f684.png" alt="G{Z6EW1D]NQLMYN{RAGQ8XE.png">&lt;br>&lt;/p>&lt;p>&lt;img src="https://pangyd.com/uploads/2017/09/e853617ca79bbad1.png" alt="PK(3H{P}~]LYL_[N4XVH9]1.png">&lt;br>&lt;/p>&lt;p>一切跟着流程走 然后提交审核就可以 如果有什么不对 客服会给你打电话 让你修改 基本上就一个工作日时间就可以通过初审&lt;/p>&lt;p>通过初审后 会让你用幕布拍照（ps:第一次备案的还需要买幕布 一般三天左右幕布才会给邮过来 &amp;nbsp;但是有个好消息就是博主这里有块幕布 离的近的小伙伴可以来找我 ）&lt;/p>&lt;p>然后你得下载一个审核单 &amp;nbsp;然后去打印社打印出来 标准就是楼下博主的标准&lt;/p></description></item><item><title>MMA你听说过吗？</title><link>https://pangyd.com/post/87-mma/</link><pubDate>Sat, 02 Sep 2017 17:43:18 +0800</pubDate><guid>https://pangyd.com/post/87-mma/</guid><description>&lt;p style="text-align: left">&lt;b>&lt;img src="https://pangyd.com/uploads/2017/09/bddbdb1b1b3bf05e.png" alt="0DE392FA28041152B3F1B8C64294CD97.png">&lt;/b>&lt;/p>&lt;p style="text-align: left">MMA？MMA是什么？目前，这三个字母大多数人表示听都没有听过，今天有幸请来了一MMA运动员史祚政，来谈一下MMA是什么？&lt;/p>&lt;p style="text-align: left">史祚政，国家职业资格私人健身教练，散打运动员，2015年任山东大学综合技击散打部部长，MMA综合搏击运动员（职业战绩19战14胜5负），国家级MMA教练员，“中国MMA第一人，中国综合搏击不败之王，林海飞豹”敖海林亲授弟子。目前，其受教人数达几百人以上……&lt;/p>&lt;p style="text-align: left">&amp;nbsp; &amp;nbsp; MMA是Mixed Martial Arts的简称，中文名称综合搏击，是集各种技击运动为一体的综合，包括散打，泰拳，柔术，摔跤，跆拳道等，我觉得形容MMA呢，就是一场有少许规则的街头格斗，既能站立打击也能进入地面，古代的打擂台和这个类型就很像，最初呢，叫做无规则格斗，也叫做无限制格斗，顾名思义，肯定是被认为比较狠的一种运动，这种运动还没发展多少年，更何况搏击是一个小众化的项目，所以没听说过很正常。&lt;/p>&lt;p style="text-align: left">&amp;nbsp; 这项运动对于防身来说效果怎么样？&lt;/p>&lt;p style="text-align: left">我觉得对于防身来说肯定是特别有用的，毕竟这项运动包括的竞技项目有很多，前面说过，我站着可以给你打，摔倒了，即使你把我摔倒了，我也有可能赢了你，因为这项运动有很多可以扭转局面的技术，例如一些关节技。&lt;/p>&lt;p style="text-align: left">&lt;br>&lt;/p>&lt;p style="text-align: left">这项运动的发展肯定会越来越好，目前，中国也培养出来了很多MMA出色的运动冠军，例如敖海林，张铁泉，李景亮，宁广友，杨建平等人，现在李景亮更是成为了一个明星选手，在ufc上（MMA顶级赛事）展现出男神本色。他们也为中国MMA的发展做了很多的贡献&lt;/p>&lt;p style="text-align: left">在此呢，我也希望更多的人来了解这项运动，支持这项运动……&lt;/p>&lt;p style="text-align: left">&lt;br>&lt;/p>&lt;p style="text-align: left">&lt;b>&lt;br>&lt;/b>&lt;/p>&lt;p>&lt;/p></description></item><item><title>每个程序员半小时内必须解决的5个编程问题</title><link>https://pangyd.com/post/85-5/</link><pubDate>Fri, 01 Sep 2017 20:41:03 +0800</pubDate><guid>https://pangyd.com/post/85-5/</guid><description>&lt;p>&lt;span>每次我发布&lt;/span>&lt;span>软件工程师&lt;/span>&lt;span>的岗位工作要求，各种求职申请就会纷至沓来，接踵而至。但每每让我困惑的是，似乎总有那么几位应聘者完全不明白所谓“编程”的意思。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;img class="" title="5-problems-programmer-1-hour" data-src="https://pangyd.com/uploads/2017/09/74c10f869f038762.jpg" width="720" height="475" data-ratio="0.6597222222222222" data-w="720" data-type="jpeg" src="https://pangyd.com/uploads/2017/09/74c10f869f038762.jpg" data-fail="0" style="text-align: center">&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;strong>&lt;span>当然，他们另有想法。&lt;/span>&lt;/strong>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>而我认为，如果你应聘的是“Web前端开发”岗位，那么你只懂jQuery也可以胜任，那么，“软件工程师”是不是就意味着会HTML、JavaScript和CSS这些必备技能就行了呢？&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>（我觉得那些聊起XML、JSON、XSLT、SOAP、HTTP、REST、SSL和200多个首字母缩写词来头头是道，但却不会区分整型和浮点型数据类型的家伙很有意思。呵呵）&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;strong>&lt;span>&lt;br>&lt;/span>&lt;/strong>&lt;/span>&lt;/p>&lt;h2>&lt;span>&lt;strong>&lt;span>你真的会写代码吗？&lt;/span>&lt;/strong>&lt;/span>&lt;/h2>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>对于应聘&lt;/span>&lt;span>程序员&lt;/span>&lt;span>的求职人员，我，作为用人单位，首先希望的是你会写代码。我指的是真正的代码：我给你一个问题，你使用任何你觉得舒适的编程语言给出它的解决方案。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;h2>&lt;span>&lt;strong>&lt;span>你真的能做到这一点吗？&lt;/span>&lt;/strong>&lt;/span>&lt;/h2>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>策略：如果你不能在半小时以内解决以下5个问题，那么你首先要做的是重新审视自己。的确，或许你各方面的工作都干的不错，但是我依然觉得你现在还不配“软件工程师（或程序员，计算机科学专家，甚至是“开发人员”）”这个头衔。不要自欺欺人，先花点时间来调整你的重点吧。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;h2>&lt;span>&lt;strong>&lt;span>5个问题&lt;/span>&lt;/strong>&lt;/span>&lt;/h2>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;strong>&lt;span>问题1&lt;/span>&lt;/strong>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>使用for循环、while循环和递归写出3个函数来计算给定数列的总和。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;strong>&lt;span>问题2&lt;/span>&lt;/strong>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>编写一个交错合并列表元素的函数。例如：给定的两个列表为[a，B，C]和[1，2，3]，函数返回[a，1，B，2，C，3]。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;strong>&lt;span>问题3&lt;/span>&lt;/strong>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>编写一个计算前100位斐波那契数的函数。根据定义，斐波那契序列的前两位数字是0和1，随后的每个数字是前两个数字的和。例如，前10位斐波那契数为：0，1，1，2，3，5，8，13，21，34。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;strong>&lt;span>问题4&lt;/span>&lt;/strong>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>编写一个能将给定非负整数列表中的数字排列成最大数字的函数。例如，给定[50，2，1,9]，最大数字为95021。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>Ps：&lt;/span>&lt;span>点击这里&lt;/span>&lt;span>，阅读我的解决方案。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;strong>&lt;span>问题5&lt;/span>&lt;/strong>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>编写一个在1，2，…，9（顺序不能变）数字之间插入+或-或什么都不插入，使得计算结果总是100的程序，并输出所有的可能性。例如：1 + 2 + 34 – 5 + 67 – 8 + 9 = 100。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>如果你能力超群，上面这些问题对你而言只是小菜一碟，0.5小时之内解决完全绰绰有余的话，请将我的慷慨陈词当作是在放屁。&lt;/span>&lt;/p>&lt;ul class="list-paddingleft-2">&lt;li>&lt;p>&lt;span>来自：码农网&lt;/span>&lt;/p>&lt;/li>&lt;li>&lt;p>&lt;span>链接：www.codeceo.com/article/5-problems-programmer-1-hour.html&lt;/span>&lt;/p>&lt;/li>&lt;li>&lt;p>&lt;span>英文原文：https://blog.svpino.com/2015/05/07/five-programming-problems-every-software-engineer-should-be-able-to-solve-in-less-than-1-hour&lt;/span>&lt;/p>&lt;/li>&lt;li>&lt;p>&lt;span>翻译作者：码农网 – 小峰&lt;/span>&lt;/p>&lt;/li>&lt;/ul></description></item><item><title>如何掌握所有的程序语言</title><link>https://pangyd.com/post/84/</link><pubDate>Thu, 31 Aug 2017 19:57:47 +0800</pubDate><guid>https://pangyd.com/post/84/</guid><description>&lt;p>对的，我这里要讲的不是如何掌握一种程序语言，而是所有的……&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>很多编程初学者至今还在给我写信请教，问我该学习什么程序语言，怎么学习。由于我知道如何掌握“所有”的程序语言，总是感觉这种该学“一种”什么语言的问题比较低级，所以一直没来得及回复他们 :P 可是逐渐的，我发现原来不只是小白们有这个问题，就连美国大公司的很多资深工程师，其实也没搞明白。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>今天我有动力了，想来统一回答一下这个搁置已久的“初级问题”。类似的话题貌似曾经写过，然而现在我想把它重新写一遍。因为在跟很多人交流之后，我对自己头脑中的（未转化为语言的）想法，有了更精准的表达。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>如果你存在以下的种种困惑，那么这篇文章也许会对你有所帮助：&lt;/p>&lt;p>你是编程初学者，不知道该选择什么程序语言来入门。&lt;/p>&lt;p>你是资深的程序员或者团队领导，对新出现的种种语言感到困惑，不知道该“投资”哪种语言。&lt;/p>&lt;p>你的团队为使用哪种程序语言争论不休，发生各种宗教斗争。&lt;/p>&lt;p>你追逐潮流采用了某种时髦的语言，结果两个月之后发现深陷泥潭，痛苦不堪……&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>虽然我已经不再过问这些世事，然而无可置疑的现实是，程序语言仍然是很重要的话题，这个情况短时间内不会改变。程序员的岗位往往会要求熟悉某些语言，甚至某些奇葩的公司要求你“深入理解 OOP 或者 FP 设计模式”。对于在职的程序员，程序语言至今仍然是可以争得面红耳赤的宗教话题。它的宗教性之强，以至于我在批评和调侃某些语言（比如 Go 语言）的时候，有些人会本能地以为我是另外一种语言（比如 Java）的粉丝。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>显然我不可能是任何一种语言的粉丝，我甚至不是 Yin 语言的粉丝 ;) 对于任何从没见过的语言，我都是直接拿起来就用，而不需要经过学习的过程。看了这篇文章，也许你会明白我为什么可以达到这个效果。理解了这里面的东西，每个程序员都应该可以做到这一点。嗯，但愿吧。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>重视语言特性，而不是语言&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>很多人在乎自己或者别人是否“会”某种语言，对“发明”了某种语言的人倍加崇拜，为各种语言的孰优孰劣争得面红耳赤。这些问题对于我来说都是不存在的。虽然我写文章批评过不少语言的缺陷，在实际工作中我却很少跟人争论这些。如果有其它人在我身边争论，我甚至会戴上耳机，都懒得听他们说什么 ;) 为什么呢？我发现归根结底的原因，是因为我重视的是“语言特性”，而不是整个的“语言”。我能用任何语言写出不错的代码，就算再糟糕的语言也差不了多少。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>任何一种“语言”，都是各种“语言特性”的组合。打个比方吧，一个程序语言就像一台电脑。它的牌子可能叫“联想”，或者“IBM”，或者“Dell”，或者“苹果”。那么，你可以说苹果一定比 IBM 好吗？你不能。你得看看它里面装的是什么型号的处理器，有多少个核，主频多少，有多少 L1 cache，L2 cache……，有多少内存和硬盘，显示器分辨率有多大，显卡是什么 GPU，网卡速度，等等各种“配置”。有时候你还得看各个组件之间的兼容性。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>这些配置对应到程序语言里面，就是所谓“语言特性”。举一些语言特性的例子：&lt;/p>&lt;p>变量定义&lt;/p>&lt;p>算术运算&lt;/p>&lt;p>for 循环语句，while 循环语句&lt;/p>&lt;p>函数定义，函数调用&lt;/p>&lt;p>递归&lt;/p>&lt;p>静态类型系统&lt;/p>&lt;p>类型推导&lt;/p>&lt;p>lambda 函数&lt;/p>&lt;p>面向对象&lt;/p>&lt;p>垃圾回收&lt;/p>&lt;p>指针算术&lt;/p>&lt;p>goto 语句&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>这些语言特性，就像你在选择一台电脑的时候，看它里面是什么配置。选电脑的时候，没有人会说 Dell 一定是最好的，他们只会说这个型号里面装的是 Intel 的 i7 处理器，这个比 i5 的好，DDR3 的内存 比 DDR2 的快这么多，SSD 比磁盘快很多，ATI 的显卡是垃圾…… 如此等等。&lt;/p></description></item><item><title>怎么开始使用Java机器学习？</title><link>https://pangyd.com/post/83-java/</link><pubDate>Wed, 30 Aug 2017 20:36:01 +0800</pubDate><guid>https://pangyd.com/post/83-java/</guid><description>&lt;p>本文咱们会做一个&lt;a target="_blank" href="https://pangyd.com/">java&lt;/a>的机械进修的重要框架的疾速概述，并证实Java机械进修是何等轻易上手，不必要你重新努力别辟门户或许从头开端创立算法。&lt;div>&lt;br>&lt;/div>&lt;div>￼&lt;/div>&lt;div>开端Java机械进修的最佳工具是甚么?&lt;/div>&lt;div>这个成绩曾经有一段时间了，但近来这些日子险些每个人都在评论辩论人工智能和机械进修。这曾经再也不是一个保留给科学家和研究者的机密，而是险些完成于每一项新兴技巧中。&lt;/div>&lt;div>鄙人面的章节中，咱们会做一个java的机械进修的重要框架的疾速概述，并证实Java机械进修是何等轻易上手，不必要你重新努力别辟门户或许从头开端创立算法。&lt;/div>&lt;div>人类的人工智能&lt;/div>&lt;div>人工智能在一段时间以来是一个普遍而且炫酷的范畴，但老是感到有点难以涉及，是特别为科学家所做。假如你想发明一个人工智能体系，你必需完成你自己的焦点算法，而且练习它们能辨认形式，懂得图象而且处置自然说话。&lt;/div>&lt;div>近来对付这范畴的蜕变使得其对付非研究者能更轻易涉及。你如今能轻易涉及到相干算法和工具。你不必要晓得你正在做甚么，然则能很轻松的晋升你应用的机械进修才能。&lt;/div>&lt;div>让机械运行&lt;/div>&lt;div>为了更简单的论述，咱们决议选出3个名目赞助你开端：&lt;/div>&lt;div>1.Deeplearning4J (DL4J) –开源，分布式，JVM的贸易深度进修lib库&lt;/div>&lt;div>2. BID Data Project –可以或许运行疾速、大规模的机械进修和数据挖掘的形式聚集&lt;/div>&lt;div>3. Neuroph –面向工具的神经收集&lt;/div>&lt;div>趁便说一下, 咱们近来宣布了别的一些吸引咱们留意的风趣的开源&lt;a target="_self" href="https://github.com/As-before">GitHub&lt;/a>库. 下载.&lt;/div>&lt;div>DL4J – 深度进修&lt;/div>&lt;div>DL4J是一个能赞助你设置装备摆设多层神经收集的工具。它为JVM供给了深度进修且随同疾速原型计划和大规模定制，同时重视比设置装备摆设更多的商定。&lt;/div>&lt;div>这个工具是为了赞助曾经领有创立和应用神经收集的实践，但不想亲身完成算法的那些人。你可以或许在海量数据上办理特定成绩和自定义神经收集属性。&lt;/div>&lt;div>DL4J 是由Java说话编写的，可以或许兼容任何JVM说话好比 Clojure, Scala, ,Kotlin，而且可以或许与Hadoop和Spark集成。&lt;/div>&lt;div>能够的应用案例包括评估或保举体系如(CRM，adtech， churn prevention)，猜测阐发乃至讹诈检测。假如你要探求实在的案例，你可以或许下载 Rapidminer. 这是应用DL4J的开源平台，用来为用户简化猜测阐发进程。&lt;/div>&lt;div>创立一个新的神经收集犹如创立一个新名目同样轻易。&lt;/div>&lt;div>BID Data Project (大数据名目)&lt;/div>&lt;div>大数据名目是由那些必要处置大批数据而且对机能敏感的人创立的。 UC Berkeley名目是由很多硬件、软件和计划形式聚集而成，能在上应用疾速、大规模的数据挖掘。&lt;/div>&lt;div>第一个库是 BIDMach，在单节点或集群上的惯例机械进修成绩都有记载。你可以或许应用这个库治理数据源，在CPU或许GPU上优化、分派数据。&lt;/div>&lt;div>BidMach 外面包括很多流行的机械进修算法，他们团队正致力于开辟分布式神经收集、图形算法和其余模子&lt;/div>&lt;div>其余两个库分别是BIDMat和 BIDParse。BIDMat是存眷与数据挖掘的疾速数学矩阵库，BIDParse是GPU加快的自然说话剖析。大数据名目标其余类库还包括可视化工具，可以或许支撑在Spark乃至在安卓运行的类库。&lt;/div>&lt;div>BIDMach基准比其余办理计划持续表现出更好的成果。乃至将其在繁多机械上的运行与其余计划在大集群上的运行比拟也是如斯。在这里可以或许找到一个完备的基准列表。&lt;/div>&lt;div>Neuroph&lt;/div>&lt;div>neuroph是用来开辟常用的神经收集构架的轻量级java框架。该框架供给了一个java库和一个GUI工具(称为easyNeurons)，你可以或许用它来在java名目中创立和练习自己的神经收集。&lt;/div>&lt;div>Neuroph包括一个开源的java类库和大批对应根本神经收集观点的基类。对付刚开端应用神经收集，或许想晓得它们若何事情的人来讲，Neuroph是个异常好的垫脚石。&lt;/div>&lt;div>你可以或许测验考试Neuroph的在线演示，看看它是怎样运行的。提醒：界面看起来很旧且过期，但你可以或许用它来创立美好的器械。它还得过2013的 Duke’s Choice的奖项。&lt;/div>&lt;div>￼&lt;/div>&lt;div>收集视图&lt;/div>&lt;div>其余名目若何呢?&lt;/div>&lt;div>万一以上三个名目不是你所必要的，你想为你的名目探求一些分歧的，也不要紧。假如你在&lt;a target="_self" href="https://github.com/As-before">GitHub&lt;/a>上搜刮“机械进修”，将有1506个Java资本让你找到适合的工具。&lt;/div>&lt;div>举个例子， Airbnb中有个风趣的名目是aerosolve,一个计划成具备人类友爱性的机械进修库。&lt;/div>&lt;div>开端进修一项新的技巧很费事，假如您希冀获得一些赞助，确保你曾经下载了Takipi的差错阐发工具。&lt;/div>&lt;div>最后的思虑&lt;/div>&lt;div>每隔几年就会有些对付人工智能的新声响。这一次，它伴跟着机械进修，数据挖掘，神经收集等等的强化来了，咱们都很支撑。这些类库开源的现实意味着这些信息和才能正奇货可居，而你一切所做的是思虑领有这个才能可以或许做成甚么。&lt;/div>&lt;div>假如你晓得其余风趣的名目或许你觉得咱们遗漏点甚么，咱们等待鄙人面的批评里见到它们。&lt;/div>&lt;div>￼&lt;/div>&lt;/p></description></item><item><title>那些程序员谈论的新技术我竟从没听说过！</title><link>https://pangyd.com/post/82/</link><pubDate>Tue, 29 Aug 2017 20:57:14 +0800</pubDate><guid>https://pangyd.com/post/82/</guid><description>&lt;p>过去的几个月里发生的几件事情，让给政府做软件开发的人感受到压力的陡增，从奥巴马的医保网站饱受诟病到美国退伍军人事务部官方网站的预约系统从1985年起就没有更新过，这些事情让我回忆起曾经作为政府程序员的经历，以及这段经历如何变成一种一直督促我努力工作的思想动力。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>我曾在某个政府部门维护过一个写于1990年代的老系统。当一个新的系统启动开发来替代部分的老系统功能时，很多的程序员对开发新系统的工作产生的严重的抵制心里。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>起初，我并不知道为什么他们会有这么大的反感。对这个系统维护一段时间之后，我才慢慢明白，有些程序员是专门维护系统，时间长达15年之久。当被邀请开发新系统时，他们对新事物和新技术都感到心里没底。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>￼&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>这让我警醒：这种事情也会很容易发生在我的职业生涯中。我可能会安逸的干着某一种工作，安逸的年年维护着某个系统。当这个系统长岁数时，我对它也变的更有价值，我的角色会最终变成专职维护它。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>我的余生也就整天执行相同的任务，直到退休。而当有一天，当这个系统不再被人需要时，我会发现外面的世界已经日新月异，我需要从头学起。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>这可不是我希望的生活轨迹；我作为程序员喜欢的方式是学习新思路来解决新问题，而不是安于现状。我们程序员很容易迷住某一项技术而将全部精力都放在上面，对于其它的毫不关心。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>虽然这样可以让你在某一个领域成为专家，但你却得不到探索其它领域获得的更多好处。当意识到这种目光狭窄会扼杀我的进取心后，我开始避免让所有鸡蛋都放到一个篮子里，我开始走出自己职业仕途中的安逸环境。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>学习新技术&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>你一直在用PHP编程吗？尝试一下使用Rails或ASP.NET。也许尝试一种新的语言或框架会让你感到受挫和沮丧，但探索的趣味也就在这里。至少，你应该看看同一种功能用其它语言是如何实现的。如何你只会用锤子，那你眼里所有的东西看起来都像钉子。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>￼&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>不惧怕老代码&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>虽然上面我举例的那个老代码的例子有些极致，但我并不认为所有的老代码都应该立刻替换掉、删掉。在如今的软件中，有很多稳固的、良好设计的程序代码，它们对那些只会使用集成开发组件的现代程序员来说是很好的学习教材。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>如果你的公司里有老项目、老代码需要你去维护，研究一&lt;/p>&lt;p>下！你会吃惊于从中学到那么多的编程知识以及公司的业务规则。还会发现一些当前正在研究的问题，其实几年以前就有人已经解决了。&lt;/p>&lt;p>￼&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>了解你的敌人&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>程序员很容易对某种语言或框架产生宗教式的虔诚。如果你发现自己曾经痛恨或鄙视某种技术(参看Jeff Atwood的一篇经典文章)，也许你应该强迫自己去研究一下它们。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>最不济，至少你能证明讨厌它们是有理由的。最好的情况是，你会从它们中学到很多东西。不要让你的偏见阻挡了你的探索道路。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>￼&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>不要太贪心&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>程序员很容易被各种层出不穷的新平台、新语言、新工具、新类库吓倒。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>你很容易产生一种恐惧心理，感觉自己已经落后——那些程序员谈论的技术我怎么从来没有听说过？当你发现一种新技术看起来很有用或很有趣时，做个笔记，几周或几月后在回来看看它，如果人们还在谈论它，那么，你就应该进一步研究它。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>事实上很多热门新技术都是昙花一现，你完全可以忽略它，不要让它们浪费了你的大脑。&lt;/p>&lt;p>￼&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>学无止境&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>程序员都有着一种天生的好奇心，这种好奇心引导着我们的编程生涯。写几行代码，装载到计算机里，让它按照你的思路工作，这是非常有趣的事情。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>但随着开发的东西越来越多，我们变的越来越忙，这种好奇心会慢慢的减退。我们应该时不时的用一些新思路挑战自己，让自己的思想保持锋锐和专注，提醒自己为什么当初选择码农这条道路。&lt;/p></description></item><item><title>优秀Java程序员的编程风格</title><link>https://pangyd.com/post/81-java/</link><pubDate>Mon, 28 Aug 2017 20:27:03 +0800</pubDate><guid>https://pangyd.com/post/81-java/</guid><description>&lt;p>格式规范：&lt;/p>&lt;p>1.缩进嵌套的代码：在每个代码块和嵌套中加入缩进，缩进代码，加强可读性。这些地方包括【类定义，内部类定义，方法定义，静态块，for循环语句，if-else语句，try、catch和finally块，匿名内部类，while语句，do-while语句】&lt;/p>&lt;p>2.断开很长的句子：第一，如果包含了逗号，那么在每一个逗号后面都另起一行，把逗号后面的每一个表达式都和逗号前面的表达式的第一个字母对齐。第二，应该在优先级最低的运算符之前断行。&lt;/p>&lt;p>3.使用空白：关键字和左括号之间，右括号和紧随其后的关键字，除了”.”之外的运算符与其前后的表达式之间用空格隔开。每个逻辑上独立的方法和代码段之间，定义类或者接口的成员之间，每个类和接口之间应该加入空白行。&lt;/p>&lt;p>4.不要直接使用Tab控制符：不同环境对Tab控制符的解释也是不同的。&lt;/p>&lt;p>命名约定：&lt;/p>&lt;p>1.名称应该具有实际意义&lt;/p>&lt;p>2.使用人们熟悉的名称&lt;/p>&lt;p>3.谨慎使用过长的名字，可以使用简明通用的缩写&lt;/p>&lt;p>4.尽量保留元音字母&lt;/p>&lt;p>5.缩写词的第一个字母大写&lt;/p>&lt;p>6.不要使用大小写来区分的名字&lt;/p>&lt;p>包命名：&lt;/p>&lt;p>1.用你所在组织的域名的倒序小写形式作为包的根限定词&lt;/p>&lt;p>2.使用单独的小写词作为每个包的根名&lt;/p>&lt;p>3.仅当新旧版本二进制兼容的时候，其包可以使用相同的名字，否则，请使用新名字&lt;/p>&lt;p>类型命名：&lt;/p>&lt;p>1.类和接口名中的每个单词的第一个字母大写&lt;/p>&lt;p>类命名：&lt;/p>&lt;p>1.用名词命名类&lt;/p>&lt;p>2.具有成组相关属性，静态服务或者常量的类名字使用复数形式&lt;/p>&lt;p>接口命名：&lt;/p>&lt;p>1.用名词或者形容词命名接口&lt;/p>&lt;p>方法命名：&lt;/p>&lt;p>1.方法名中的第一个单词小写，其后每个单词的第一个字母大写&lt;/p>&lt;p>2.用动词命名方法&lt;/p>&lt;p>3.遵循JavaBean中命名属性访问函数方法：set，get，is&lt;/p>&lt;p>变量命名：&lt;/p>&lt;p>1.变量命中的第一个单词小写，其后的每个单词的第一个字母大写&lt;/p>&lt;p>2.用名词命名变量&lt;/p>&lt;p>3.集合引用名要用复数形式&lt;/p>&lt;p>4.为不重要的临时变量简历并使用一套标准名字&lt;/p>&lt;p>字段命名：&lt;/p>&lt;p>1.使用this字段变量可以区分开局部变量&lt;/p>&lt;p>参数命名：&lt;/p>&lt;p>1.构造函数或者”set”方法给字段分配参数赋值，参数名应该和字段名相同&lt;/p>&lt;p>常量命名：&lt;/p>&lt;p>1.常量的每个单词均大写，单词之间使用下划线连接&lt;/p>&lt;p>文档约定：&lt;/p>&lt;p>1.为使用和维护你的代码的人编写文档&lt;/p>&lt;p>2.注释和代码要同步&lt;/p>&lt;p>3.使用积极的语气，省略无用的词语&lt;/p>&lt;p>注释类型：&lt;/p>&lt;p>1.用文档注释来描述编程接口&lt;/p>&lt;p>2.用标准注释格式隐藏代码而不必删除它们&lt;/p>&lt;p>3.用单行注释解释实现细节&lt;/p>&lt;p>文档注释：&lt;/p>&lt;p>1.在编写代码前描述编程接口&lt;/p>&lt;p>2.为公用，受保护，包，私有成员建立文档&lt;/p>&lt;p>3.为每个包编写总结和概述&lt;/p>&lt;p>4.为包的每个应用程序或组编写概述&lt;/p>&lt;p>注释风格：&lt;/p>&lt;p>1.对所有文档注释使用统一的格式和组织结构&lt;/p>&lt;p>2.关键字，标识符和常量应放到&amp;lt;code&amp;gt;…&amp;lt;/code&amp;gt;标签中&lt;/p>&lt;p>3.将代码放入&amp;lt;pre&amp;gt;…&amp;lt;/pre&amp;gt;标签中&lt;/p>&lt;p>4.在标识符第一次出现的时候用{@link}标签&lt;/p>&lt;p>5.为Javadoc标签简历并使用一套固定的顺序&lt;/p>&lt;p>6.使用第三人称叙述的形式&lt;/p>&lt;p>7.编写独立的概述&lt;/p>&lt;p>8.省略概述中动作和服务的主语&lt;/p>&lt;p>9.省略事物概述中的对象和动词&lt;/p>&lt;p>10.使用this而不是the来指代当前类中的实例&lt;/p>&lt;p>11.方法名或者构造函数名不需圆括号，除非你想突出一个特殊的签名&lt;/p>&lt;p>注释内容：&lt;/p>&lt;p>1.每个类、接口、字段和方法都编写概述&lt;/p>&lt;p>2.完整描述每个方法的签名&lt;/p>&lt;p>3.包含示例&lt;/p>&lt;p>4.为前置、后置、不变条件编写文档&lt;/p>&lt;p>5.为已知的缺陷和不足编写文档&lt;/p>&lt;p>6.为同步语法编写文档&lt;/p></description></item><item><title>Java中堆内存和栈内存详解</title><link>https://pangyd.com/post/80-java/</link><pubDate>Sun, 27 Aug 2017 19:13:26 +0800</pubDate><guid>https://pangyd.com/post/80-java/</guid><description>&lt;p>Java把内存分成两种，一种叫做栈内存，一种叫做堆内存.&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配。当在一段代码块中定义一个变量时，java就在栈中为这个变量分配内存空间，当超过变量的作用域后，java会自动释放掉为该变量分配的内存空间，该内存空间可以立刻被另作他用。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>堆内存用于存放由new创建的对象和数组。在堆中分配的内存，由java虚拟机自动垃圾回收器来管理。在堆中产生了一个数组或者对象后，还可以在栈中定义一个特殊的变量，这个变量的取值等于数组或者对象在堆内存中的首地址，在栈中的这个特殊的变量就变成了数组或者对象的引用变量，以后就可以在程序中使用栈内存中的引用变量来访问堆中的数组或者对象，引用变量相当于为数组或者对象起的一个别名，或者代号。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>引用变量是普通变量，定义时在栈中分配内存，引用变量在程序运行到作用域外释放。而数组＆对象本身在堆中分配，即使程序运行到使用new产生数组和对象的语句所在地代码块之外，数组和对象本身占用的堆内存也不会被释放，数组和对象在没有引用变量指向它的时候，才变成垃圾，不能再被使用，但是仍然占着内存，在随后的一个不确定的时间被垃圾回收器释放掉。这个也是java比较占内存的主要原因，实际上，栈中的变量指向堆内存中的变量，这就是 Java 中的指针!&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>java中内存分配策略及堆和栈的比较&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>1 内存分配策略&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>按照编译原理的观点,程序运行时的内存分配有三种策略,分别是静态的,栈式的,和堆式的.&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>静态存储分配是指在编译时就能确定每个数据目标在运行时刻的存储空间需求,因而在编译时就可以给他们分配固定的内存空间.这种分配策略要求程序代码中不允许有可变数据结构(比如可变数组)的存在,也不允许有嵌套或者递归的结构出现,因为它们都会导致编译程序无法计算准确的存储空间需求.&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>栈式存储分配也可称为动态存储分配,是由一个类似于堆栈的运行栈来实现的.和静态存储分配相反,在栈式存储方案中,程序对数据区的需求在编译时是完全未知的,只有到运行的时候才能够知道,但是规定在运行中进入一个程序模块时,必须知道该程序模块所需的数据区大小才能够为其分配内存.和我们在数据结构所熟知的栈一样,栈式存储分配按照先进后出的原则进行分配。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>静态存储分配要求在编译时能知道所有变量的存储要求,栈式存储分配要求在过程的入口处必须知道所有的存储要求,而堆式存储分配则专门负责在编译时或运行时模块入口处都无法确定存储要求的数据结构的内存分配,比如可变长度串和对象实例.堆由大片的可利用块或空闲块组成,堆中的内存可以按照任意顺序分配和释放.&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>2 堆和栈的比较&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>上面的定义从编译原理的教材中总结而来,除静态存储分配之外,都显得很呆板和难以理解,下面撇开静态存储分配,集中比较堆和栈:&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>从堆和栈的功能和作用来通俗的比较,堆主要用来存放对象的，栈主要是用来执行程序的.而这种不同又主要是由于堆和栈的特点决定的:&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>在编程中，例如C/C++中，所有的方法调用都是通过栈来进行的,所有的局部变量,形式参数都是从栈中分配内存空间的。实际上也不是什么分配,只是从栈顶向上用就行,就好像工厂中的传送带(conveyor belt)一样,Stack Pointer会自动指引你到放东西的位置,你所要做的只是把东西放下来就行.退出函数的时候，修改栈指针就可以把栈中的内容销毁.这样的模式速度最快, 当然要用来运行程序了.需要注意的是,在分配的时候,比如为一个即将要调用的程序模块分配数据区时,应事先知道这个数据区的大小,也就说是虽然分配是在程序运行时进行的,但是分配的大小多少是确定的,不变的,而这个”大小多少”是在编译时确定的,不是在运行时.&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>堆是应用程序在运行的时候请求操作系统分配给自己内存，由于从操作系统管理的内存分配,所以在分配和销毁时都要占用时间，因此用堆的效率非常低.但是堆的优点在于,编译器不必知道要从堆里分配多少存储空间，也不必知道存储的数据要在堆里停留多长的时间,因此,用堆保存数据时会得到更大的灵活性。事实上,面向对象的多态性,堆内存分配是必不可少的,因为多态变量所需的存储空间只有在运行时创建了对象之后才能确定.在C++中，要求创建一个对象时，只需用 new命令编制相关的代码即可。执行这些代码时，会在堆里自动进行数据的保存.当然，为达到这种灵活性，必然会付出一定的代价:在堆里分配存储空间时会花掉更长的时间!这也正是导致我们刚才所说的效率低的原因,看来列宁同志说的好,人的优点往往也是人的缺点,人的缺点往往也是人的优点(晕~).&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>3 JVM中的堆和栈&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>JVM是基于堆栈的虚拟机.JVM为每个新创建的线程都分配一个堆栈.也就是说,对于一个Java程序来说，它的运行就是通过对堆栈的操作来完成的。堆栈以帧为单位保存线程的状态。JVM对堆栈只进行两种操作:以帧为单位的压栈和出栈操作。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>我们知道,某个线程正在执行的方法称为此线程的当前方法.我们可能不知道,当前方法使用的帧称为当前帧。当线程激活一个Java方法,JVM就会在线程的 Java堆栈里新压入一个帧。这个帧自然成为了当前帧.在此方法执行期间,这个帧将用来保存参数,局部变量,中间计算过程和其他数据.这个帧在这里和编译原理中的活动纪录的概念是差不多的.&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>从Java的这种分配机制来看,堆栈又可以这样理解:堆栈(Stack)是操作系统在建立某个进程时或者线程(在支持多线程的操作系统中是线程)为这个线程建立的存储区域，该区域具有先进后出的特性。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>每一个Java应用都唯一对应一个JVM实例，每一个实例唯一对应一个堆。应用程序在运行中所创建的所有类实例或数组都放在这个堆中,并由应用所有的线程共享.跟C/C++不同，Java中分配堆内存是自动初始化的。Java中所有对象的存储空间都是在堆中分配的，但是这个对象的引用却是在堆栈中分配,也就是说在建立一个对象时从两个地方都分配内存，在堆中分配的内存实际建立这个对象，而在堆栈中分配的内存只是一个指向这个堆对象的指针(引用)而已。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>Java 中的堆和栈&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>Java把内存划分成两种：一种是栈内存，一种是堆内存。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>当在一段代码块定义一个变量时，Java就在栈中为这个变量分配内存空间，当超过变量的作用域后，Java会自动释放掉为该变量所分配的内存空间，该内存空间可以立即被另作他用。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>堆内存用来存放由new创建的对象和数组。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>在堆中分配的内存，由Java虚拟机的自动垃圾回收器来管理。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>在堆中产生了一个数组或对象后，还可以在栈中定义一个特殊的变量，让栈中这个变量的取值等于数组或对象在堆内存中的首地址，栈中的这个变量就成了数组或对象的引用变量。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>引用变量就相当于是为数组或对象起的一个名称，以后就可以在程序中使用栈中的引用变量来访问堆中的数组或对象。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>具体的说：&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>栈与堆都是Java用来在Ram中存放数据的地方。与C++不同，Java自动管理栈和堆，程序员不能直接地设置栈或堆。&lt;/p></description></item><item><title>在BAT工作和创业公司工作有什么不同的体验？</title><link>https://pangyd.com/post/79-bat/</link><pubDate>Sat, 26 Aug 2017 21:57:37 +0800</pubDate><guid>https://pangyd.com/post/79-bat/</guid><description>&lt;p>这个问题的答案会因为发问人的不同而不同。别人永远无法回答“你应该去哪里”这个问题。更有意义的方法是，分别去看在BAT和创业公司里，你会得到什么、不得不接受什么，在此基础上，做出最符合自己现状且最能实现未来期许的选择。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>如果在BAT级别的公司工作，体验如何？&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>在这样的公司工作，你能收获：&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>1、公司品牌为个人品牌做背书。同时，由此会获得很多资源和人脉。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>2、更大更全面的行业格局和视野。小而美的事情多由创业公司完成。而战略格局之类的事，则是大公司在做。在BAT对于建立行业视野和格局有很大帮助。很多时候，先了解大背景，再切入小事情，效率和方向都会更对。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>3、和很多精英接触并学习。尽管随着人员扩张而精英比例减少，但是，精英仍然很多。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>4、专业的工作方法。尽管互联网整体专业性弱于金融业或外企，但是BAT的专业性在互联网行业基本最强，创业公司没有精力顾及专业这件事。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>5、充足的学习成长空间。这一点是相对创业公司而言的。没有生存压力的BAT有能力招纳新人并给予三个月到半年的学习期。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>6、了解多条业务发展，有更全局的判断和更充分的信息储备。小公司一般就一条业务，但是大公司的业务线很多。观察越多，业务逻辑就越全面、行业知识也越深厚。很多时候，信息的充足度会影响决定的正确性。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>7、BAT的员工量级都在几万人。去观察公司如何凭借统一流程有效管理这么多员工，也是一件很有意思的事情。能够提升个人的管理水平。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>在BAT工作，你不得不接受：&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>1、个体竞争激烈，出头不易。这是对平均水平同学的泛指，对于格外优秀的人才，在哪都发光。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>2、办公室政治。有人的地方就有江湖，越大的公司，政治斗争越激烈。无穷尽的扯皮，开会，斗争，都是再正常不过的。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>3、细到蛋疼的分工。每件事都需要很多很多个团队配合完成，盖因分工细。分工细是社会进步的表现，但是从具体项目而言，却是降低效率的原因。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>4、漫长复杂的流程。没办法，要规模化管理几万人，必须要有安全的流程。同时由于分工细，流程中也要涉及太多不同的角色，所以流程漫长得不得了。这是个正常现象。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>5、没有话语权的弱势地位。除非你特别出色，对公司特别重要，不然，就基本不会有议价的话语权。除非在团队里有资格对自己的老板议价，同时老板在更大的体系里也有和公司议价的能力，不然，只能一边抱怨，一边忍受。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>很多人从BAT出逃，就是因为忍受不了这些“不得不”条款。那么，在一个小的创业公司工作，是不是就天高云阔、万物和谐，恰好能够规避这些？并不尽然。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>先看看在创业公司，你能够收获什么。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>1、更有诱惑力的实现“财务自由”的未来。很多人进创业公司，看中的恰恰是“可能上市”这个结果。一旦成功，可获得的财务收益将是在BAT大公司打工十几、几十年的总和。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>2、更全面的实践机会。不同于大公司，创业公司没有细致分工，也没有严格流程。由于分工模糊，凡是个人能力所及的都可尝试，学习的广度增加;由于没有流程限制，效率高，可快速试错。实践出真知，一个员工在创业公司一年实践所学，将是在BAT的3倍以上。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>3、和精英更近距离的接触。不同于BAT的严格级别限制，在创业公司的扁平化结构中，普通员工也能与创始人们频繁接触。优秀创业公司创始人，在BAT也会是总监及以上。接触精英的机会增加，受益匪浅。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>4、更大的成就感。由于创业公司品牌弱、用户少，日常工作对业务的促进显著可见，个人成就感增加。在BAT，很多时候是无法了解自己的工作到底为业务带来什么样的价值。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>但是，想要快速融入创业公司，并跟着公司一起高速发展，却也要面对很多无法规避的阵痛。记住一句话：在创业公司，为生存而发展大于一切。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>1、工作重，压力大，易焦虑。创业公司通常都面临着巨大的行业竞争压力，跑不快则死。这种公司压力折射到员工身上，就是繁重的工作任务、习以为常的加班时间，和弥漫全公司的焦虑感。因此，在创业公司工作，需要有极强的抗压能力和适应性，管理情绪，做好自我调节。同时，要接受“没有自己的生活”这个状态。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>2、无流程带来的混乱，无管理带来的反弹。在享受无流程的高效率的同时，也要忍受由此引发的混乱;在享受扁平化快速行动的同时，也要忍受公司管理制度不足带来的各种不满。对于创业公司来说，发展大于一切，流程、管理方法、专业的工作方法等，会影响发展效率。同时，在精力有限的情况下，管理层确实也无法顾及这些相对“务虚”的事项。这些混乱和反弹，需要个体自我消化。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>3、只有最基本的福利保障。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>4、干活全靠自己。在BAT还有团队干活?到了创业公司，很长一段时间，你都得习惯自己动手丰衣足食。小到每个错别字，大到每个战略方向，都要赤膊上阵自己来。同时，由于公司小，资源少，行业内话语权弱，谈合作基本靠刷脸。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>只要是选择，就一定会有“好”和“不好”，世上从无完美选择。无论是选择什么样的工作环境，在做决定前，都有以下原则可以遵循：&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>1、尽可能获得足够信息。信息越多，决策风险越低。既可以主动收集线上信息，也可以多做面对面沟通。有时候非正式沟通，更易获得有小细节。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>2、明确自己的长远目标。以目标为导向，倒推实现路径，选择最match实现路径的决定。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>3、了解决策成本，预估决策收益。评估自己是否可以承担成本，多大可能获得收益。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>4、评估选择后的发展空间。使前路更广阔的选择，一般来说优于减少未来可能性的选择。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>5、记住一点，职场上，不要幻想温情。无论是哪个选择，其结果成否都要靠你的实力说话。与感情无关。鲜事，传播TMT大事件&lt;/p>&lt;p>来源：网站分析公会&lt;/p></description></item><item><title>程序员，如何从平庸走向理想？</title><link>https://pangyd.com/post/78/</link><pubDate>Fri, 25 Aug 2017 21:10:04 +0800</pubDate><guid>https://pangyd.com/post/78/</guid><description>&lt;p>我算是靠坑蒙拐骗进了程序员的门，然后一路狂奔。26 岁之前几乎没有任何写代码的经验，研究生毕业却意外选择了一家不可能提供培训的初创公司，在每日担忧公司倒闭、害怕被炒鱿鱼以及同事冷落白眼的三重压力下逆流而上，一年半后离职，已是拥有 500 万用户产品的后台主程。从前我对计算机技术心怀畏惧，认定技术高人一定有佛光笼罩，昼夜不息运键如飞日吐代码上万行。现在也算见过一些世面了，回首那段忐忑不安宛如初夜的过程，我却不发觉有任何的励志意味，而是视为一种理所当然。理想的程序员，和理想的建筑师、理想的财务师、理想的按摩师没有任何的差别，他们本质上都是一群手艺人。我相信理想的程序员人人皆可成为。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>近三年总在互联网圈厮混，我认识过一些程序员，共事过一些程序员，领导过一些程序员，又面试过一些程序员。他们学历不同，有的来自北大，有的来自北大青鸟，有的是博士，有的是高中肄业；资历也不同，有的来自 BAT，有的来自某破产基金公司（还是一个销售）；年限也从 0 到 15 年不等。但我认为程序员只需分三类：天才的程序员、理想的程序员、平庸的程序员。天才的程序员我只敢说接触过 3 个，这是天命。7 分由你是颗精子的时候就已决定，拥有绝佳的数学天赋、冷静致密的逻辑、为解决难题宁愿不眠不休而深以为乐的技术热情；3 分来自起步要早早早，恨不得同龄人玩泥巴的时候就得开始玩电脑，大学毕业前就突破一万小时法则，后面的已是游戏人生。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>天才的程序员可遇不可求，更不能长有，我看到的 90% 仍是平庸的程序员。IT时代的膨胀，已让程序员如同文艺复兴时的印刷匠一样的普通，多数投入祖师爷门下的人，仅是为了更大的饭碗，更高的待遇，更好的生计。平庸的程序员编写腐烂的代码，没有规范和一致性，固守旧世界的语言，还好谈论大的架构和性能，说的比做的漂亮。而毫无例外的，他们认定技术没有出路，做产品、营销和管理的是更高大上的手艺，而他们当中的 99%，又会自然的流露出自己恰巧具备了那方面的天赋，至于进程为什么会崩溃这样的小问题是不屑于去了解的。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>而我最喜欢和理想的程序员相处，恨不得与他们同吃同住，如果允许，我希望我的队伍能插满他们的旗帜。理想的程序员心眼儿不坏（他们从来都不是办公室政治的宠儿，是一群单纯明亮快乐的手艺人），有天真烂漫的好奇心（他们的眼睛里经常闪着「哇，这个是怎么做到的！」），永远精益求精（他们的口头禅是「我再研究一下」），还乐于分享（他们活跃于 GitHub、各大问答社区和你的身边，舍得将宝贵时间用于帮助新手）。是的，他们不需要被管理，只需要给一个大的方向，总能回报以意想不到的结果。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>理想的程序员与平庸的程序员只有一墙之隔。两者的差距只有 6 个一点点，而人与人的差距，正是在这日积月累的一点点中，被永远拉开了。有意思的是，我发现这6个一点点都和意识有关，也就是程序员和其他一切新兴产业的工种一样，只需要意识加上时间的锤炼，人人皆可达到理想的阶段。理想的程序员必然也是一个优秀的 problem-solver.&lt;/p>&lt;p>第 1 个一点点：专注眼下&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>见过太多心猿意马的程序员，我不得不把「专注眼下」作为天字第一条。他们往往有各式各样的小梦想，比如做个小茶农、做个小鹅贩、做产品、做销售、做投资，却被程序员的高薪或是没有转行的魄力「耽误」了，而因为不专注，他们不在意做好自己的本分，不在意锤炼自己的技能，不在意学习新兴的技术。不可否认，这世界上存在着伟大的产品（像乔老爷）、伟大的销售（像埃里森）、伟大的投资客（像彼得菲），而他们毫无例外都是程序员出身。可你听说过巴菲特评价盖茨的话么，比尔盖茨如果转行去卖狗，那他一定是全世界最大的狗贩。我坚信除了少数的天才外，冥冥众生均可以在多个领域取得成功，只要保持足够的专注。而哪怕你下一年就想卖狗去，程序员的经验仍然能训练你强大的逻辑、谨慎和耐心，放在哪个行业都是相当可观的竞争力。&lt;/p>&lt;p>第 2 个一点点：思考力与推动力&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>我认为处理 bug、崩溃、调优、入侵等突发事件比编程本身更能体现平庸程序员与理想程序员的差距。当面对一个未知的问题时，如何定位复杂条件下的核心问题、如何抽丝剥茧地分析问题的潜在原因、如何排除干扰还原一个最小的可验证场景、如何抓住关键数据验证自己的猜测与实验，都是体现程序员思考力的最好场景。是的，在衡量理想程序员的标准上，思考力比经验更加重要。&lt;/p>&lt;p>有时候小伙伴跑过来，问我「提交了一个任务被卡住了，怎么办」的时候，我总觉得他可以做得更好。比如，可以检查试验别的任务，以排除代码自身的原因；可以通过 Web UI 检查异常（如果没有账号，可以让我提供）；可以排查主机日志或删除缓存，再不济，总应该提供任务 ID 和控制台日志给我。理想的程序员永远不会等事情前进，他们会用尽一切方法让事情前进。&lt;/p>&lt;p>第 3 个一点点：Never Say No&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>记得从前厂离职之前，找老板谈话，他说我最大的优点就是从来不和他说这个做不到。后来我发现在很多团队里，都存在一种技术和产品的对立，程序员往往以「技术上无法实现」来挡产品的需求，而产品也往往以「Facebook可以为什么我们做不到」来奚落程序员。这两句话应该属于禁语，从根本上都不利于程序猿和产品狗的相亲相爱。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>一句「技术上无法实现」是容易出口，可有多少人在说出这句话的时候，心里是 100% 肯定的？如果不肯定，为什么不能回去谷歌一下再回答？原本我以为程序员是充满想象力，在因为有想象力，才能诞生那么多改变我们生活的软件和互联网产品。见识多了，才了解大部分程序员已经在与 bug 的对抗中变得保守而不愿担当风险，与此同时许多团队也不愿意宽容失败。于是「Say No」变成一种习惯性的抵触，还记得曾国藩为什么解散湘军么？他说那支军队已「暮气渐深」，不能打仗了。要做理想的程序员，就不能给自己滋生暮气的机会，如果面对不合理的需求，可以把时间成本摆出来，把曲线救国方案亮出来，简单粗暴「Say No」是不可取的。&lt;/p>&lt;p>第 4 个一点点：投资未来&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>程序员是一个非常残忍的职业。你所学所用的语言、框架、模式，很可能在数年内就成昨日黄花了；你现在嘲笑的另一群程序员，可能马上就能转身来嘲笑你了。所以理想的程序员除了做好自己的本分，还要花费时间来投资未来。什么是「投资」？投资就是你现在投入的时间，在未来会以更多的时间或者金钱（看看早几年学习 iOS 的程序员现在的薪酬！）回报你。举我自己的领域 — 数据挖掘为例，08 年左右 Hadoop 开始兴起，一时「大数据」概念火热，Hadoop 工程师万金难求，各互联网公司纷纷把数据统计、数据分析和数据挖掘的业务切换到分布式平台上。这几年眼看 Hadoop 还在不断迭代，Spark 又异军突起，一举刷新了 Hadoop 保持的排序记录，以内存存储中间数据带来的性能优势和丰富的数据结构让人爱个不停，各种奇异的小 bug 和陡峭的学习曲线又让人打退堂鼓。那么，明眼人都知道 Spark 是未来的趋势（内存会越来越便宜），在主业务放在 Hadoop 的条件下，就可以适当把一些小模块切换到 Spark 上，同时留意 Spark 社区的发展。很快从 Spark 获得的性能收益就能把之前投入的学习时间挣回来。&lt;/p></description></item><item><title>搞 Java 的程序员，年薪 40W 需要什么水平？</title><link>https://pangyd.com/post/76-java-40w/</link><pubDate>Wed, 23 Aug 2017 15:20:47 +0800</pubDate><guid>https://pangyd.com/post/76-java-40w/</guid><description>&lt;p style="text-align: center">&lt;span>前几天在网上看到这么一个问题， 搞Java的程序员年薪40w 是个什么水平？&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;span>一下勾起了我的&lt;span>兴趣，今天就来简单分析下，到底是什么水平。&lt;/span>&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;br>&lt;/p>&lt;p style="text-align: center">那么我们先来搞清楚"JAVA"是谁家姑娘？&lt;/p>&lt;p style="text-align: center">&lt;img class="__bg_gif " data-ratio="0.845" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.gif" data-type="gif" data-w="200" _width="auto" src="https://pangyd.com/uploads/2017/08/74c10f869f038762.gif" data-order="1" data-fail="0">&lt;/p>&lt;p style="text-align: center">&lt;span>......&lt;/span>&lt;/p>&lt;p style="text-align: center">&lt;span>不不不，方向搞错了。。&lt;/span>&lt;/p>&lt;p style="text-align: center">那么我们先来搞清楚，年薪40W，这个是税前还是税后。&lt;br>•阿里薪资结构：一般是12+1+3=16薪&lt;br>•年底的奖金为0-6个月薪资，90%人可拿到3个月&lt;br>&lt;img class="" data-ratio="0.47" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpeg" data-type="jpeg" data-w="600" _width="auto" src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpeg" data-fail="0">&lt;br>&lt;span>&lt;strong>&lt;img class="" data-ratio="1.6153846153846154" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.png" data-type="png" data-w="13" width="8px" _width="8px" src="https://pangyd.com/uploads/2017/08/74c10f869f038762.png" data-fail="0">&lt;/strong>&lt;/span>&lt;br>&lt;span>&lt;strong>&lt;img class="" data-ratio="1.6153846153846154" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.png" data-type="png" data-w="13" width="8px" _width="8px" src="https://pangyd.com/uploads/2017/08/74c10f869f038762.png" data-fail="0">&lt;/strong>&lt;/span>&lt;br>&lt;strong>&lt;img class="" data-ratio="1.6153846153846154" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.png" data-type="png" data-w="13" width="8px" _width="8px" src="https://pangyd.com/uploads/2017/08/74c10f869f038762.png" data-fail="0">&lt;/strong>&lt;br>&lt;strong>&lt;img class="" data-ratio="1.6153846153846154" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.png" data-type="png" data-w="13" width="8px" _width="8px" src="https://pangyd.com/uploads/2017/08/74c10f869f038762.png" data-fail="0">&lt;/strong>&lt;br>&lt;span>&lt;strong>&lt;img class="" data-ratio="1.6153846153846154" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.png" data-type="png" data-w="13" width="8px" _width="8px" src="https://pangyd.com/uploads/2017/08/74c10f869f038762.png" data-fail="0">&lt;/strong>&lt;/span>&lt;br>&lt;span>&lt;strong>&lt;img class="" data-ratio="1.6153846153846154" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.png" data-type="png" data-w="13" width="8px" _width="8px" src="https://pangyd.com/uploads/2017/08/74c10f869f038762.png" data-fail="0">&lt;/strong>&lt;/span>&lt;br>&lt;strong>&lt;img class="" data-ratio="1.6153846153846154" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.png" data-type="png" data-w="13" width="8px" _width="8px" src="https://pangyd.com/uploads/2017/08/74c10f869f038762.png" data-fail="0">&lt;/strong>&lt;br>&lt;strong>&lt;img class="" data-ratio="1.6153846153846154" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.png" data-type="png" data-w="13" width="8px" _width="8px" src="https://pangyd.com/uploads/2017/08/74c10f869f038762.png" data-fail="0">&lt;/strong>&lt;/p></description></item><item><title>我见过的最糟糕的代码</title><link>https://pangyd.com/post/75/</link><pubDate>Wed, 23 Aug 2017 14:19:01 +0800</pubDate><guid>https://pangyd.com/post/75/</guid><description>&lt;p>&lt;span>多数的客户项目，在任务完成之后都会很快从记忆里消退，但有些你一辈子都不会忘记。今天这篇文章，我要说的就属于后者。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>这事发生在很多年前，在一个相当大的公司里，公司名我就不说了。那个软件有一大堆程序，是一个商业系统的核心模块，由一个、单独的小伙维护着，这个家伙不久前被炒了。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>像这样的事情其实都很正常，一些公司通常会发现他们的一些关键性技术自始至终都保存在一个人的头脑里，当有事情发生时，就像现在这个人，你通常会经历一阵痛苦阶段去阅读他留下的东西，之后生活慢慢趋于正常。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>这次有点不一样。&lt;/span>&lt;/p>&lt;p>&lt;img class="" data-ratio="0.6222910216718266" data-s="300,640" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-type="png" data-w="646" _width="auto" src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-fail="0">&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>这个程序出了点问题，公司派了一个去修复这个问题，等他回来后发现精神有点反常，不是哭就是笑，嘴里嘟囔着什么“&lt;span>匹萨调用汉堡，并且传入了包子&lt;/span>”。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>程序员的代码里通常体现着自己对幽默的理解，以及对‘工作保密’这个词的认识。我们都听说过一些难以置信的故事，比如说公司辞退了某个搞技术的家伙后，结果被告知如不在 48 小时内向某个海外账户打入多少钱，会计软件将会自动删除所有客户记录。像这种的小伎俩相对而言还好处理 —— 假设这些传说的故事大多数都是真的，我还是很难相信，我从来没有在现实生活中遇到过这种事情。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>这个家伙留下来的软件里没有任何的逻辑炸弹或下流的阴谋，编译很正常，除了有一个 bug 外，一切都工作的很好。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>但是，你需要想像一下：程序中的所有函数、变量名都是以食物命名的。&lt;span>匹萨，西红柿，泡菜，各种味道的奶酪，水果，蔬菜，酒&lt;/span>，等等，一篇一篇，全是这样。里面唯一能让你马上知道意义的地方，只有 ‘main’ 函数名和 C 标准类库的调用。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>就这样，我接手了这个费力不讨好的烂摊子，努力把程序恢复到一个可维护的状态。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>说实话，这是一个极好的加密形式，只有拿到密钥你才能让这些“代码沙拉“变得有意义。一点一点的，我把这些函数名和变量名改成具有意义的命名，开始很麻烦，之后慢慢的变得容易些。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>把已知的函数和源代码进行恢复，要比对未知的代码进行反向解析容易的多，因为首先你要分清代码里哪些是程序，哪些是数据，而放在我前面的这些程序，显然都是明文，所有这活儿并不是不可能完成，或者说是格外的困难，只是这活儿太乏味太无趣了。一旦你发现了某个变量可能应该给个什么样有意义的名字，余下的就是查找和替换。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;/p>&lt;p>&lt;img class="" data-ratio="0.6424501424501424" data-s="300,640" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-type="jpeg" data-w="702" _width="auto" src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-fail="0">&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>另外一个问题是，代码写的太烂，事实上，这意大利面条式的代码，比这些毫无意义的符号更让人困惑，等我把函数名和变量名都改回有意义的名称后，我开始把一大堆的代码重写，让它们易于理解、效率更高。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>我始终没有弄明白他是否还有一套没有加密混淆过的代码，他可以使用一些‘混淆’脚本通过替换的方法把原始变量名混淆成这样。我很难相信，一个人会在最初时就把代码写成这样，因为这对他自己也是一个巨大的挑战，这里肯定有一些高超的技术。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>当然，如果你的脑子里还在想：你不能因为我的变量名没有什么意义就把我开除了(或应该招我回来改程序)，那你是在妄想，不管这个家伙的用意是什么，他的做法十分的错误(我很难想象他的前任老板还会推荐他)，不管怎样，这事儿让我乐了好几周。&lt;/span>&lt;/p></description></item><item><title>Java My SQL 数据库 用法操作代码</title><link>https://pangyd.com/post/74-java-my-sql/</link><pubDate>Tue, 22 Aug 2017 14:09:56 +0800</pubDate><guid>https://pangyd.com/post/74-java-my-sql/</guid><description>&lt;p>&lt;span>各数据库连接代码&lt;/span>&lt;/p>&lt;p>&lt;span>&amp;nbsp;//Oracle8/8i/9i&lt;/span>&lt;span>数据库&lt;/span>&lt;span>(thin&lt;/span>&lt;span>模式&lt;/span>&lt;span>)&amp;nbsp;&lt;/span>&lt;/p>&lt;p>&lt;span>&amp;nbsp;&amp;nbsp;String&amp;nbsp;url="jdbc:&lt;a href="https://lib.csdn.net/base/oracle" class="replace_word" title="Oracle知识库" target="_blank">oracle&lt;/a>:thin:@localhost:1521:orcl";&amp;nbsp;&lt;/span>&lt;/p>&lt;p>&lt;span>&amp;nbsp;&amp;nbsp;String&amp;nbsp;user="scott";&amp;nbsp;&lt;/span>&lt;/p>&lt;p>&lt;span>&amp;nbsp;&amp;nbsp;String&amp;nbsp;password="tiger";&amp;nbsp;&lt;/span>&lt;/p>&lt;p>&lt;span>&amp;nbsp;&amp;nbsp;Connection&amp;nbsp;conn=DriverManager.getConnection(url,user,password);&amp;nbsp;&lt;/span>&lt;/p>&lt;p>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/p>&lt;p>&lt;span>&amp;nbsp;&amp;nbsp;//Sql&amp;nbsp;Server7.0/2000/2005/2008&lt;/span>&lt;span>数据库&amp;nbsp;&lt;/span>&lt;/p>&lt;p>&lt;span>&amp;nbsp;&amp;nbsp;String&amp;nbsp;url="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=pubs";&amp;nbsp;&lt;/span>&lt;/p>&lt;p>&lt;span>&amp;nbsp;&amp;nbsp;String&amp;nbsp;user="sa";&amp;nbsp;&lt;/span>&lt;/p>&lt;p>&lt;span>&amp;nbsp;&amp;nbsp;String&amp;nbsp;password="";&amp;nbsp;&lt;/span>&lt;/p>&lt;p>&lt;span>&amp;nbsp;&amp;nbsp;Connection&amp;nbsp;conn=DriverManager.getConnection(url,user,password);&amp;nbsp;&lt;/span>&lt;/p>&lt;p>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/p>&lt;p>&lt;span>&amp;nbsp;&amp;nbsp;//DB2&lt;/span>&lt;span>数据库&amp;nbsp;&lt;/span>&lt;/p>&lt;p>&lt;span>&amp;nbsp;&amp;nbsp;String&amp;nbsp;url="jdbc:db2://localhost:5000/sample";&amp;nbsp;&lt;/span>&lt;/p>&lt;p>&lt;span>&amp;nbsp;&amp;nbsp;String&amp;nbsp;user="amdin"&amp;nbsp;&lt;/span>&lt;/p>&lt;p>&lt;span>&amp;nbsp;&amp;nbsp;String&amp;nbsp;password=-"";&amp;nbsp;&lt;/span>&lt;/p>&lt;p>&lt;span>&amp;nbsp;&amp;nbsp;Connection&amp;nbsp;conn=DriverManager.getConnection(url,user,password);&amp;nbsp;&lt;/span>&lt;/p>&lt;p>&lt;span>&amp;nbsp;&amp;nbsp;&lt;/span>&lt;/p>&lt;p>&lt;span>//MySQL&lt;/span>&lt;span>数据库&amp;nbsp;&lt;/span>&lt;/p>&lt;p>&lt;span>String&amp;nbsp;url="jdbc:mysql://localhost:3306/testDB?user=root&amp;amp;password=root&amp;amp;useUnicode=true&amp;amp;characterEncoding=gb2312";&amp;nbsp;&lt;/span>&lt;/p>&lt;p>&lt;span>Connection&amp;nbsp;conn=DriverManager.getConnection(url);&amp;nbsp;&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>一下是进行增删改查的mysql代码&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>增：insert into user//表名(***//表头) values(****//增加的数据)";&lt;/p>&lt;p>改：update user//表名 set userName//表头 ='"+field2+"//修改的数据',passwork='"+field3+"',teacherID="+Integer.parseInt(field4)+" where userID="+Integer.parseInt(field1);&lt;/p>&lt;p>删：delete from user where userID="+Integer.parseInt(field1//字符串类型的要先转换成整型的);&lt;/p>&lt;p>查：select * from userID//查询表中的某个表头 order by User//&lt;a target="_self" href="https://github.com/As-before">表名&lt;/a>&lt;/p></description></item><item><title>三十五年经验分享：程序员进阶八法</title><link>https://pangyd.com/post/73/</link><pubDate>Mon, 21 Aug 2017 19:44:14 +0800</pubDate><guid>https://pangyd.com/post/73/</guid><description>&lt;p>&lt;span>这八法十分可靠，可提高你写代码的技能，你可要收藏好了。&lt;/span>&lt;/p>&lt;p>&lt;br data-filtered="filtered">&lt;/p>&lt;p>&lt;span>时间到了，提高你的编程技能，认真+严肃，走起！&lt;/span>&lt;/p>&lt;p>&lt;br data-filtered="filtered">&lt;/p>&lt;p>&lt;span>如果你的目标仅仅是提高自己，那么很容易实现，但是如果你的目标是成为一个伟大的程序员，那么这就不简单了。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>很多人都愿意说，我想变得更好，但是更好是什么却很模糊，而且人们也不知道该怎么样去做。&lt;/span>&lt;/p>&lt;p>&lt;br data-filtered="filtered">&lt;/p>&lt;p>&lt;span>我在这里分享八法来帮助你顺利提高你的编程技能。这些小智慧来自三十年深耕该领域，许多都令你再熟悉不过了，你可能早就认知了它们。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;section class="">&lt;section>&lt;span>&lt;/span>&lt;span>&lt;span>&lt;/span>&lt;span>&lt;/span>&lt;/span>&lt;/section>&lt;section>&lt;section class="">&lt;section>&lt;span>1.要记得，你并非无所不知&lt;/span>&lt;/section>&lt;/section>&lt;/section>&lt;/section>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>在你前进的路上，有一只巨大的拦路虎，它的名字叫做“我无所不知”。那些计算机学科毕业的大学生们以及有经验的程序员都好犯这样的毛病。&lt;/span>&lt;/p>&lt;p>&lt;br data-filtered="filtered">&lt;/p>&lt;p>&lt;span>实际上，这是一个陷阱，掉进去就很难爬上来。但是，你仍然要克服它。只有机器人才愿意认为自己无所不知，但是人类的特点是，能够认识到自己的不足，然后去学习新知。&lt;/span>&lt;/p>&lt;p>&lt;br data-filtered="filtered">&lt;/p>&lt;p>&lt;span>所以，你要明白，想要成为一个更好的程序员，第一步就是意识到自己总有新物要学，保持谦逊的态度，这才是学习的一贯正途。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;section class="">&lt;section>&lt;span>&lt;/span>&lt;span>&lt;span>&lt;/span>&lt;span>&lt;/span>&lt;/span>&lt;/section>&lt;section>&lt;section class="">&lt;section>&lt;span>2.停止去证明你有多正确吧&lt;/span>&lt;/section>&lt;/section>&lt;/section>&lt;/section>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>从经验中学习会令你伟大，而不仅仅是还凑合。但是要注意了，经验也会使我们不断重复错误的行为导致养成不好的习惯。如果你是有8年经验的程序员，你也有可能连着8年都在重复同样的错误。&lt;/span>&lt;/p>&lt;p>&lt;br data-filtered="filtered">&lt;/p>&lt;p>&lt;span>克服这一谬感的方法就是，时刻检视自己，并不断地发问：在这一点上，我是否还能做得更好一些。&lt;/span>&lt;/p>&lt;p>&lt;br data-filtered="filtered">&lt;/p>&lt;p>&lt;span>举个有趣儿的例子，一个经验丰富的软件开发者，他写出了令自己也艳羡不已的代码，于是他觉得这个代码简直太完美了，他不断写文章去证明自己有多么的正确，代码功能多么优秀。&lt;/span>&lt;/p>&lt;p>&lt;br data-filtered="filtered">&lt;/p>&lt;p>&lt;span>氮素呢？人们从来没有见到他去找一切办法来佐证自己的代码是错误的。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>其实呀，真正优秀的程序员，他们都喜欢去证反，就是去证明自己有多么的错误，因为他们知道，长久来看，用户一定会发现软件的问题和失误，而他们希望自己首先发现这些问题，而不是等待别人去发现。&lt;/span>&lt;/p>&lt;p>&lt;br data-filtered="filtered">&lt;/p>&lt;p>&lt;span>呐，你看到优秀和平庸之间的差距了吗？&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;section class="">&lt;section>&lt;span>&lt;/span>&lt;span>&lt;span>&lt;/span>&lt;span>&lt;/span>&lt;/span>&lt;/section>&lt;section>&lt;section class="">&lt;section>&lt;span>3.代码没有死亡，它始终活着&lt;/span>&lt;/section>&lt;/section>&lt;/section>&lt;/section>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>没错，你第一步总是要写出高质量的代码来满足用户的特殊需求，但是优秀和平庸的区别体现在哪里？&lt;/span>&lt;/p>&lt;p>&lt;br data-filtered="filtered">&lt;/p>&lt;p>&lt;span>如果你只是匆匆忙忙地进入下一个任务中，那么你不可避免地成为了穷忙族。一段代码写出来以后，它并没有死亡，它始终活着。&lt;/span>&lt;/p>&lt;p>&lt;br data-filtered="filtered">&lt;/p>&lt;p>&lt;span>这说明什么？你写出代码并不意味着你的工作结束了，相反，一切都才刚刚开始，你不需要火急火燎地赶往下一个站点。&lt;/span>&lt;/p>&lt;p>&lt;br data-filtered="filtered">&lt;/p>&lt;p>&lt;span>停止，仅仅意味着阶段性的展示和赏析，但是伟大的程序员对一件事情心知肚明，那就是万事都可以更好，产品运行了，这很棒，但是你的工作没有结束，要依靠迭代让产品变得好上加好。&lt;/span>&lt;/p>&lt;p>&lt;br data-filtered="filtered">&lt;/p>&lt;p>&lt;span>如何让产品变得更好？我们依据不同的应用，会提出不同的问题，比如，更快是不是对产品价值的增值？更容易记录是不是呢？更容易重复使用呢？更可靠呢？&lt;/span>&lt;/p>&lt;p>&lt;br data-filtered="filtered">&lt;/p>&lt;p>&lt;span>这些问题虽然不同，但是程序猿对产品不懈追求的动机是一致的。你懂了吗？你不断思考如何让产品变得更好，这一点是不变的，但是你的方法是提出一些与众不同的、内容不一的问题。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;section class="">&lt;section>&lt;span>&lt;/span>&lt;span>&lt;span>&lt;/span>&lt;span>&lt;/span>&lt;/span>&lt;/section>&lt;section>&lt;section class="">&lt;section>&lt;span>4.写三次吧&lt;/span>&lt;/section>&lt;/section>&lt;/section>&lt;/section>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>好的程序员认为写出的软件能运行就好了，伟大的程序员认为软件要运行得极其完美。但这很少在第一次就成功，最好的软件通常要写三次。&lt;/span>&lt;/p>&lt;p>&lt;br data-filtered="filtered">&lt;/p>&lt;p>&lt;span>首先，你写软件是为了向自己或者用户证明问题是可以解决的。其他人或许意识不到这是一个概念生成的时期，但是你自己很清楚。&lt;/span>&lt;/p>&lt;p>&lt;br data-filtered="filtered">&lt;/p>&lt;p>&lt;span>然后，你让软件生效。最后，你让它正确地运行。&lt;/span>&lt;/p>&lt;p>&lt;br data-filtered="filtered">&lt;/p></description></item><item><title>那些程序员谈论的新技术我竟从没听说过！</title><link>https://pangyd.com/post/72/</link><pubDate>Mon, 21 Aug 2017 19:41:15 +0800</pubDate><guid>https://pangyd.com/post/72/</guid><description>&lt;p>&lt;span>过去的几个月里发生的几件事情，让给政府做软件开发的人感受到压力的陡增，从奥巴马的医保网站饱受诟病到美国退伍军人事务部官方网站的预约系统从1985年起就没有更新过，这些事情让我回忆起曾经作为政府程序员的经历，以及这段经历如何变成一种一直督促我努力工作的思想动力。&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>我曾在某个政府部门维护过一个写于1990年代的老系统。当一个新的系统启动开发来替代部分的老系统功能时，很多的程序员对开发新系统的工作产生的严重的抵制心里。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>起初，我并不知道为什么他们会有这么大的反感。对这个系统维护一段时间之后，我才慢慢明白，有些程序员是专门维护系统，时间长达15年之久。当被邀请开发新系统时，他们对&lt;span>&lt;strong>新事物和新技术都感到心里没底&lt;/strong>。&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;img class="__bg_gif " data-ratio="0.476" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-type="gif" data-w="500" width="100%" _width="670px" src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-order="1" data-fail="0">&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>&lt;strong>&lt;span>这让我警醒：&lt;/span>&lt;/strong>&lt;span>这种事情也会很容易发生在我的职业生涯中。我可能会安逸的干着某一种工作，安逸的年年维护着某个系统。当这个系统长岁数时，我对它也变的更有价值，我的角色会最终变成专职维护它。&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>我的余生也就整天执行相同的任务，直到退休。而当有一天，当这个系统不再被人需要时，我会发现外面的世界已经日新月异，我需要从头学起。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>这可不是我希望的生活轨迹；我作为程序员喜欢的方式是学习新思路来解决新问题，而不是安于现状。&lt;/span>&lt;span>我们程序员很容易迷住某一项技术而将全部精力都放在上面，对于其它的毫不关心。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>虽然这样可以让你在某一个领域成为专家，但你却得不到探索其它领域获得的更多好处。当意识到这种目光狭窄会扼杀我的进取心后，我开始避免让所有鸡蛋都放到一个篮子里，我开始走出自己职业仕途中的安逸环境。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;section class="" style="text-align: center">&lt;section>&lt;section>&lt;section>&lt;section>&lt;/section>&lt;section>&lt;/section>&lt;/section>&lt;section class="">&lt;section class="">&lt;section>&lt;strong>&lt;span>学习新技术&lt;/span>&lt;/strong>&lt;/section>&lt;/section>&lt;/section>&lt;/section>&lt;section>&lt;section>&lt;/section>&lt;section>&lt;/section>&lt;/section>&lt;/section>&lt;section>&lt;/section>&lt;/section>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>你一直在用PHP编程吗？尝试一下使用Rails或ASP.NET。也许尝试一种新的语言或框架会让你感到受挫和沮丧，但探索的趣味也就在这里。至少，你应该看看同一种功能用其它语言是如何实现的。如何你只会用锤子，那你眼里所有的东西看起来都像钉子。&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;/p>&lt;p>&lt;img class="__bg_gif " data-ratio="0.562" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-type="gif" data-w="500" width="100%" _width="670px" src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-order="2" data-fail="0">&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;section class="" style="text-align: center">&lt;section>&lt;section>&lt;section>&lt;section>&lt;/section>&lt;section>&lt;/section>&lt;/section>&lt;section class="">&lt;section class="">&lt;section>&lt;strong>&lt;span>不惧怕老代码&lt;/span>&lt;/strong>&lt;/section>&lt;/section>&lt;/section>&lt;/section>&lt;section>&lt;section>&lt;/section>&lt;section>&lt;/section>&lt;/section>&lt;/section>&lt;section>&lt;/section>&lt;/section>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>虽然上面我举例的那个老代码的例子有些极致，但我并不认为所有的老代码都应该立刻替换掉、删掉。在如今的软件中，有很多稳固的、良好设计的程序代码，它们对那些只会使用集成开发组件的现代程序员来说是很好的学习教材。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>如果你的公司里有老项目、老代码需要你去维护，研究一&lt;/span>&lt;/p>&lt;p>&lt;span>下！你会吃惊于从中学到那么多的编程知识以及公司的业务规则。还会发现一些当前正在研究的问题，其实几年以前就有人已经解决了。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;/p>&lt;p>&lt;img class="__bg_gif " data-ratio="0.496" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-type="gif" data-w="500" width="100%" _width="670px" src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-order="3" data-fail="0">&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;section class="" style="text-align: center">&lt;section>&lt;section>&lt;section>&lt;section>&lt;/section>&lt;section>&lt;/section>&lt;/section>&lt;section class="">&lt;section class="">&lt;section>&lt;strong>&lt;span>了解你的敌人&lt;/span>&lt;/strong>&lt;/section>&lt;/section>&lt;/section>&lt;/section>&lt;section>&lt;section>&lt;/section>&lt;section>&lt;/section>&lt;/section>&lt;/section>&lt;section>&lt;/section>&lt;/section>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>程序员很容易对某种语言或框架产生宗教式的虔诚。如果你发现自己曾经痛恨或鄙视某种技术(参看Jeff Atwood的一篇经典文章)，也许你应该强迫自己去研究一下它们。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>最不济，至少你能证明讨厌它们是有理由的。最好的情况是，你会从它们中学到很多东西。不要让你的偏见阻挡了你的探索道路。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;img class="__bg_gif " data-ratio="0.482" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-type="gif" data-w="500" _width="auto" src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-order="4" data-fail="0">&lt;/p></description></item><item><title>JAVA修改、删除数据之后刷新JTable的方法</title><link>https://pangyd.com/post/71-javajtable/</link><pubDate>Sun, 20 Aug 2017 17:04:58 +0800</pubDate><guid>https://pangyd.com/post/71-javajtable/</guid><description>&lt;p>以下代码不完整，仅把关键的代码贴出来&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>String userTitle[] = {"ID","用户名","密码","邮箱","名字","等级"};&lt;/p>&lt;p>tab = new Object[userInfoNumber][6];&lt;/p>&lt;p>&lt;span class="Apple-tab-span">&lt;/span>Iterator&amp;lt;User&amp;gt; iter = userList.iterator();&lt;/p>&lt;p>&lt;span class="Apple-tab-span">&lt;/span>while(iter.hasNext()){&lt;/p>&lt;p>&lt;span class="Apple-tab-span">&lt;/span>User user = iter.next();&lt;/p>&lt;p>&lt;span class="Apple-tab-span">&lt;/span>tab[i][0] = user.getId();&lt;/p>&lt;p>&lt;span class="Apple-tab-span">&lt;/span>tab[i][1] = user.getUserName();&lt;/p>&lt;p>&lt;span class="Apple-tab-span">&lt;/span>tab[i][2] = user.getPwd();&lt;/p>&lt;p>&lt;span class="Apple-tab-span">&lt;/span>tab[i][3] = user.getMail();&lt;/p>&lt;p>&lt;span class="Apple-tab-span">&lt;/span>tab[i][4] = user.getName();&lt;/p>&lt;p>&lt;span class="Apple-tab-span">&lt;/span>whatGrade = user.getGrade() == 1 ? "管理员" : "普通会员";&lt;/p>&lt;p>&lt;span class="Apple-tab-span">&lt;/span>tab[i][5] = whatGrade;&lt;/p>&lt;p>&lt;span class="Apple-tab-span">&lt;/span>&lt;/p>&lt;p>&lt;span class="Apple-tab-span">&lt;/span>i ++;&lt;span class="Apple-tab-span">&lt;/span>&lt;/p>&lt;p>&lt;span class="Apple-tab-span">&lt;/span>}&lt;/p>&lt;p>DefaultTableModel tableModel = new DefaultTableModel(tab,userTitle);&lt;/p>&lt;p>&lt;span class="Apple-tab-span">&lt;/span>&lt;/p>&lt;p>&lt;span class="Apple-tab-span">&lt;/span>JTable table = new JTable(tableModel);&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>for(int j = 0;j &amp;lt; table.getRowCount();j ++){&lt;/p></description></item><item><title>导出含有图片的Java项目，图片不显示</title><link>https://pangyd.com/post/69-java/</link><pubDate>Sun, 20 Aug 2017 16:55:36 +0800</pubDate><guid>https://pangyd.com/post/69-java/</guid><description>&lt;div>项目的一些图片资源文件在导出成JAR包后，无法正确读取虽然Java项目还是可以运行，但原来的图片资源全不见了，于是你可以打开JAR包看看里面的东西，确实是有图片在里面，就是无法读取。&lt;/div>&lt;p>&lt;span>其实是因为我们在导出成JAR包后，图片资源的路径已经发生了变化，造成无法读取的问题&lt;/span>&lt;/p>&lt;p>首先在项目的SRC目录下建立一个包，然后再把图片等资源放进包中，然后再通过下面的方法进行读取：&lt;/p>&lt;div>&lt;span>ImageIcon img = new ImageIcon(【你的主类名称】.class.get&lt;/span>&lt;span>getResource("/pic/index.png"));&lt;/span>&lt;/div>&lt;div>比如我在SRC目录下建立了一个pic包，包下面放了一张图片index.png，我的读取图片主类是MySample，那么我需要读取index.png这张图片时就要这样做：&lt;/div>&lt;div>&lt;span>ImageIcon indexImage = new ImageIcon(MySample.class.get&lt;/span>&lt;span>getResource("/pic/index.png"));&lt;/span>&lt;/div>&lt;div>要注意的是路径中pic前面的斜杠不可少，否则会报错读取不到资源造成空指针，其他如音频资源也是类似做法。&lt;img type="face" src="https://pangyd.com/uploads/2017/08/c8ea831c46d1b44c.gif" real_src="https://www.sinaimg.cn/uc/myshow/blog/misc/gif/E___6716EN00SIGG.gif" alt="关于JAVA的SWING项目导出可执行JAR时图片资源问题" title="关于JAVA的SWING项目导出可执行JAR时图片资源问题">&lt;/div></description></item><item><title>转载自【Java编程精选】关于 Java 你不知道的十件事</title><link>https://pangyd.com/post/68-java-java/</link><pubDate>Sat, 19 Aug 2017 20:49:33 +0800</pubDate><guid>https://pangyd.com/post/68-java-java/</guid><description>&lt;p>&lt;span>作为Java 控&lt;span>，&lt;/span>&lt;/span>&lt;span>&lt;span>我们总是对&lt;/span>&lt;span>不太可能直接使用&lt;/span>&lt;span>，&lt;/span>&lt;span>但&lt;/span>&lt;span>能使我们更&lt;/span>&lt;/span>&lt;span>&lt;span>了解&lt;/span>&amp;nbsp;Java 和 Java 虚拟机（Java Virtual Machine，JVM） 的晦涩细节感兴趣。这也是我将 Lukas Eder 在&amp;nbsp;&lt;/span>jooq.org&lt;span>&amp;nbsp;上写的这篇&lt;/span>文章&lt;span>发布出来的原因。&lt;/span>&lt;/p>&lt;p>&lt;span>你在Java发布的时候就开始使用了吗？还&lt;/span>记得那时它叫“Oak”，面向对象也 （Object Oriented， OO ）还是个热门话题，C++ 程序员们觉得 Java 完全没机会成功&lt;span>，Applet的出现也是一件新鲜大事？&lt;/span>&lt;/p>&lt;p>&lt;span>我打赌下文中&lt;/span>至少一半的内容你都不知道。让我们来看看这些令人惊喜的 Java 细节吧。&lt;/p>&lt;h2>1. 受检异常（checked exception）这件事是不存在的&lt;/h2>&lt;p>是这样的，JVM 完全不知道这件事，&lt;span>都是Java语言做的[只有Java语言这么干]。&lt;/span>&lt;/p>&lt;p>现在，&lt;span>异常检查&lt;/span>被公认为是个错误，正如 Brue Eckel 在布拉格的 GeeCON 大会上的闭幕词中所说， Java 后的其他语言&lt;span>都不再使用异常检查了，&lt;/span>就连 Java 8 都不愿在新的 Stream API 中使用它了（当你在 lambda 表达式中使用 IO 或者 JDBC 时，是很痛苦的）。&lt;/p>&lt;p>你想要&lt;span>证明 JVM 不知道异常检查这件事&lt;/span>吗？尝试以下代码：&lt;/p>&lt;p>&lt;img data-s="300,640" data-type="png" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" class="" data-ratio="0.3784246575342466" data-w="584" src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-fail="0">&lt;/p>&lt;p>&lt;span>这个不仅会编译，还会抛出 SQLException&lt;span>&amp;nbsp;，你&lt;/span>&lt;/span>&lt;span>甚至&lt;/span>&lt;span>&lt;span>不&lt;/span>需要 Lombok 的&amp;nbsp;&lt;/span>@SneakyThrows&lt;span>&amp;nbsp;标签。&lt;/span>&lt;/p>&lt;p>更多详情请参考这篇文章，或者 Stack Overflow 上的这篇文章。&lt;/p>&lt;h2>2. 可以使用不同的返回值类型来重载方法&lt;/h2>&lt;p>以下代码是编译不过的，对吧？&lt;/p>&lt;p>&lt;img data-s="300,640" data-type="png" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" class="" data-ratio="0.14492753623188406" data-w="483" src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-fail="0">&lt;/p></description></item><item><title>java.lang.StackOverflowError 异常解决办法</title><link>https://pangyd.com/post/67-java-lang-stackoverflowerror/</link><pubDate>Sat, 19 Aug 2017 19:43:46 +0800</pubDate><guid>https://pangyd.com/post/67-java-lang-stackoverflowerror/</guid><description>&lt;p style="text-align: center">&amp;nbsp;这个错误是&amp;nbsp;相互引用,导致连锁&amp;nbsp;栈溢出,不知道那块循环没有停下来 &amp;nbsp;所以进程就一直在跑&lt;/p>&lt;p style="text-align: center">我一直在找到底哪的循环没停下来&amp;nbsp;&amp;nbsp;然后还是没找到。直接调用没错误&amp;nbsp;就是加表格上就出错&amp;nbsp;别的窗口都没错误就是这个论文查询有错误&lt;/p>&lt;p style="text-align: center">&amp;nbsp;&amp;nbsp;到最后发现就是接口调用的时候写错单词了&lt;img src="https://pangyd.com/uploads/2017/08/44ddb3ea33fe01f7.gif" alt="[微笑]">&amp;nbsp;心里十万个草泥马奔腾而过&lt;/p>&lt;p style="text-align: center">这个错误的官方解释是：&lt;/p>&lt;p style="text-align: center">递归调用没有明确的结束&lt;/p>&lt;p style="text-align: center">仔细查看自己的递归调用程序&lt;/p>&lt;p style="text-align: center">举例：递归没有边界条件或者递归的边界条件永远不能达到&lt;/p>&lt;p style="text-align: center">所以你就找找你哪里少写了几句 实在不行就重写&lt;/p>&lt;p style="text-align: center">&lt;b>结论：没有找不到的Bug 只有不努力没有耐心的人&lt;/b>&lt;/p></description></item><item><title>科研管理系统--ResAbout 关于界面代码设计</title><link>https://pangyd.com/post/66-resabout/</link><pubDate>Fri, 18 Aug 2017 20:11:06 +0800</pubDate><guid>https://pangyd.com/post/66-resabout/</guid><description>&lt;pre lay-lang="Java" class="layui-code" skin="notepad">package view;

import java.awt.AWTEvent;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.Insets;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URL;
import java.net.URLClassLoader;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

import com.jnzj.common.Commom;

public class ResAbout extends JFrame implements ActionListener{
	Image icon;
	ImageIcon banner;
	JLabel jLabel;
	JLabel jLabel2;
	JLabel jLabel3;
	JLabel jLabel4;
	JLabel jLabel5;
	JPanel jPanel;
	JPanel jPanel2;
	JPanel jPanel3;
	JButton jButton;
	private GridBagConstraints girdBagCon;
	private GridBagLayout girdBag=new GridBagLayout();
	public ResAbout() {
		// TODO Auto-generated constructor stub
		this.setLayout(new BorderLayout());//边框布局
		//enableEvents(AWTEvent.WINDOW_EVENT_MASK);
		//添加框架的关闭时间处理2
		//this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		//窗口自适应大小 使窗体能正好显示里面的所有控件
		this.pack();
		//设置框架的大小
		this.setSize(500,400);
		//设置窗体的标题
		this.setTitle("关于");
		//调用自定义的方法GetImage（） ，获取图标文件
		icon=getImage("icon.png");
		//设置窗体图标
		this.setIconImage(icon);
		//设置不能调整窗体的大小
		this.setResizable(false);
		//获取屏幕大小
		Dimension screenSize=Toolkit.getDefaultToolkit().getScreenSize();
		//获取当前项目的窗体大小
		Dimension frameSize=this.getSize();
		//如果项目窗体高&amp;gt;屏幕高，用屏幕高设置项目窗体高
		if (frameSize.height&amp;gt;screenSize.height) {
			frameSize.height=screenSize.height;
		}
		if (frameSize.width&amp;gt;screenSize.width) {
			frameSize.width=screenSize.width;
		}
		//设置窗体起始显示位置 居中显示
		this.setLocation((screenSize.width-frameSize.width)/2,
		(screenSize.height-frameSize.height)/2);
		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (ClassNotFoundException | InstantiationException | IllegalAccessException
				| UnsupportedLookAndFeelException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		try {
			top();
			central();
			down();
			addListener();//监听
			this.setVisible(true);
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
		
		
	}
	private void addListener() {
		// TODO Auto-generated method stub
		jButton.addActionListener(this);
		
	}
	public void top() {
		jPanel=new JPanel();
		jPanel.setLayout(girdBag);
		jLabel=new JLabel("1.科研管理系统V1.0\t");
		jLabel.setFont(new Font("Dialog", 0, 12));
		girdBagCon=new GridBagConstraints();
		girdBagCon.gridx=0;
		girdBagCon.gridy=1;
		//外部填充 4个参数 top,left,bottom,right
		//既外部间距
		//girdBagCon.insets=new Insets(0, 10, 10, 1);
		girdBag.setConstraints(jLabel, girdBagCon);

		jLabel2=new JLabel("2.版权归2017doft公司所有 翻录必究");
		jLabel2.setFont(new Font("Dialog", 0, 12));
		girdBagCon=new GridBagConstraints();
		girdBagCon.gridx=0;
		girdBagCon.gridy=2;
		//外部填充 4个参数 top,left,bottom,right
		//既外部间距
		//girdBagCon.insets=new Insets(0, 10, 10, 1);
		girdBag.setConstraints(jLabel2, girdBagCon);
		
		jLabel3=new JLabel("3.联系方式：");
		jLabel3.setFont(new Font("Dialog", 0, 12));
		girdBagCon=new GridBagConstraints();
		girdBagCon.gridx=0;
		girdBagCon.gridy=3;
		//外部填充 4个参数 top,left,bottom,right
		//既外部间距
		//girdBagCon.insets=new Insets(0, 10, 10, 1);
		girdBag.setConstraints(jLabel3, girdBagCon);
		
		jLabel4=new JLabel("4.我们的口号是：代码演绎人生 算法助推梦想");
		jLabel4.setFont(new Font("Dialog", 0, 12));
		girdBagCon=new GridBagConstraints();
		girdBagCon.gridx=0;
		girdBagCon.gridy=4;
		//外部填充 4个参数 top,left,bottom,right
		//既外部间距
		//girdBagCon.insets=new Insets(0, 10, 10, 1);
		girdBag.setConstraints(jLabel4, girdBagCon);
		jPanel.add(jLabel);
		jPanel.add(jLabel);
		jPanel.add(jLabel2);
		jPanel.add(jLabel3);
		jPanel.add(jLabel4);	
		this.add(jPanel,BorderLayout.NORTH);
		
	}
	public void central() {
		jPanel2=new JPanel();

		banner=new ImageIcon("res/image.png");
		jLabel5=new JLabel(banner);
		jPanel2.add(jLabel5);
		this.add(jPanel2,BorderLayout.CENTER);
	}
	public void down() {
		jPanel3=new JPanel();
		this.add(jPanel3,BorderLayout.SOUTH);
		jButton=new JButton("关闭");
		jPanel3.add(jButton);
	}
	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		Object object=e.getSource();
		if (object==jButton) {
			this.setVisible(false);
		}
		
	}

	/** * 通过给定的文件名获得图像 */
	
	Image getImage(String filename){ 
		//URLClassLoader--用于从指向 jar文件和目录的 URL 的搜索路径加载类和资源。
		URLClassLoader urlLoader=(URLClassLoader) this.getClass().getClassLoader(); 
		
		URL url=null; 
		Image image=null;
		url=urlLoader.findResource(filename); 
		image=Toolkit.getDefaultToolkit().getImage(url); 
		MediaTracker mediaTracker=new MediaTracker(this); 
		 try { 
			 mediaTracker.addImage(image, 0); 
			 mediaTracker.waitForID(0); 
		 }catch (InterruptedException _ex){
			 image=null;
		 }
		 if (mediaTracker.isErrorID(0)) {
			 image=null;
		 }
		 return image;
	}
}
&lt;/pre></description></item><item><title>科研管理系统--ResHelp 帮助界面代码设计</title><link>https://pangyd.com/post/65-reshelp/</link><pubDate>Fri, 18 Aug 2017 20:08:24 +0800</pubDate><guid>https://pangyd.com/post/65-reshelp/</guid><description>&lt;pre lay-lang="Java" class="layui-code" skin="notepad">package view;

import java.awt.AWTEvent;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.Insets;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URL;
import java.net.URLClassLoader;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

import com.jnzj.common.Commom;

public class ResHelp extends JFrame implements ActionListener{
	Image icon;
	ImageIcon banner;
	JLabel jLabel6;
	JLabel jLabel;
	JLabel jLabel2;
	JLabel jLabel3;
	JLabel jLabel4;
	JLabel jLabel5;
	JPanel jPanel;
	JPanel jPanel2;
	JPanel jPanel3;
	JButton jButton;
	private GridBagConstraints girdBagCon;
	private GridBagLayout girdBag=new GridBagLayout();
	public ResHelp() {
		// TODO Auto-generated constructor stub
		this.setLayout(new BorderLayout());//边框布局
		//enableEvents(AWTEvent.WINDOW_EVENT_MASK);
		//添加框架的关闭时间处理2
		//this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		//窗口自适应大小 使窗体能正好显示里面的所有控件
		this.pack();
		//设置框架的大小
		this.setSize(700,200);
		//设置窗体的标题
		this.setTitle("帮助");
		//调用自定义的方法GetImage（） ，获取图标文件
		icon=getImage("icon.png");
		//设置窗体图标
		this.setIconImage(icon);
		//设置不能调整窗体的大小
		this.setResizable(false);
		//获取屏幕大小
		Dimension screenSize=Toolkit.getDefaultToolkit().getScreenSize();
		//获取当前项目的窗体大小
		Dimension frameSize=this.getSize();
		//如果项目窗体高&amp;gt;屏幕高，用屏幕高设置项目窗体高
		if (frameSize.height&amp;gt;screenSize.height) {
			frameSize.height=screenSize.height;
		}
		if (frameSize.width&amp;gt;screenSize.width) {
			frameSize.width=screenSize.width;
		}
		//设置窗体起始显示位置 居中显示
		this.setLocation((screenSize.width-frameSize.width)/2,
		(screenSize.height-frameSize.height)/2);
		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (ClassNotFoundException | InstantiationException | IllegalAccessException
				| UnsupportedLookAndFeelException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		try {
			top();
			central();
			down();
			addListener();//监听
			this.setVisible(true);
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
		
		
	}
	private void addListener() {
		// TODO Auto-generated method stub
		jButton.addActionListener(this);
		
	}
	public void top() {
		
		jPanel2=new JPanel();
		jPanel2.setLayout(girdBag);
		jLabel6=new JLabel("科研管理系统帮助");
		jLabel6.setFont(new Font("Dialog", 0, 16));
		girdBagCon=new GridBagConstraints();
		girdBagCon.gridx=0;
		girdBagCon.gridy=0;
		//外部填充 4个参数 top,left,bottom,right
		//既外部间距
		girdBagCon.insets=new Insets(0, 10, 0, 10);
		girdBag.setConstraints(jLabel6, girdBagCon);
		jPanel2.add(jLabel6);
		this.add(jPanel2,BorderLayout.NORTH);
	}
	public void central() {
		jPanel=new JPanel();
		jPanel.setLayout(girdBag);
		jLabel=new JLabel("1.科研管理系统是为了统计高校教师的科研成果");
		jLabel.setFont(new Font("Dialog", 0, 12));
		girdBagCon=new GridBagConstraints();
		girdBagCon.gridx=0;
		girdBagCon.gridy=1;
		//外部填充 4个参数 top,left,bottom,right
		//既外部间距
		//girdBagCon.insets=new Insets(0, 10, 10, 1);
		girdBag.setConstraints(jLabel, girdBagCon);

		jLabel2=new JLabel("2.以论文信息的统计为例子");
		jLabel2.setFont(new Font("Dialog", 0, 12));
		girdBagCon=new GridBagConstraints();
		girdBagCon.gridx=0;
		girdBagCon.gridy=2;
		//外部填充 4个参数 top,left,bottom,right
		//既外部间距
		//girdBagCon.insets=new Insets(0, 10, 10, 1);
		girdBag.setConstraints(jLabel2, girdBagCon);
		
		jLabel3=new JLabel("3.该论文系统实现了论文信息，作者信息，作者所在部门信息的管理，包括：添加，删除和修改");
		jLabel3.setFont(new Font("Dialog", 0, 12));
		girdBagCon=new GridBagConstraints();
		girdBagCon.gridx=0;
		girdBagCon.gridy=3;
		//外部填充 4个参数 top,left,bottom,right
		//既外部间距
		//girdBagCon.insets=new Insets(0, 10, 10, 1);
		girdBag.setConstraints(jLabel3, girdBagCon);
		
		jLabel4=new JLabel("4.该系统实现了论文信息，作者信息，作者和所在部门的不同条件查询");
		jLabel4.setFont(new Font("Dialog", 0, 12));
		girdBagCon=new GridBagConstraints();
		girdBagCon.gridx=0;
		girdBagCon.gridy=4;
		//外部填充 4个参数 top,left,bottom,right
		//既外部间距
		//girdBagCon.insets=new Insets(0, 10, 10, 1);
		girdBag.setConstraints(jLabel4, girdBagCon);
		jPanel.add(jLabel);
		jPanel.add(jLabel2);
		jPanel.add(jLabel3);
		jPanel.add(jLabel4);	
		this.add(jPanel,BorderLayout.CENTER);
		
	}
	public void down() {
		jPanel3=new JPanel();
		this.add(jPanel3,BorderLayout.SOUTH);
		jButton=new JButton("关闭");
		jPanel3.add(jButton);
	}
	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		Object object=e.getSource();
		if (object==jButton) {
			this.setVisible(false);
		}
		
	}

	/** * 通过给定的文件名获得图像 */
	
	Image getImage(String filename){ 
		//URLClassLoader--用于从指向 jar文件和目录的 URL 的搜索路径加载类和资源。
		URLClassLoader urlLoader=(URLClassLoader) this.getClass().getClassLoader(); 
		
		URL url=null; 
		Image image=null;
		url=urlLoader.findResource(filename); 
		image=Toolkit.getDefaultToolkit().getImage(url); 
		MediaTracker mediaTracker=new MediaTracker(this); 
		 try { 
			 mediaTracker.addImage(image, 0); 
			 mediaTracker.waitForID(0); 
		 }catch (InterruptedException _ex){
			 image=null;
		 }
		 if (mediaTracker.isErrorID(0)) {
			 image=null;
		 }
		 return image;
	}
}
&lt;/pre></description></item><item><title>科研信息管理系统-论文管理之菜单导航版</title><link>https://pangyd.com/post/64/</link><pubDate>Thu, 17 Aug 2017 17:21:03 +0800</pubDate><guid>https://pangyd.com/post/64/</guid><description>&lt;pre lay-lang="Java" class="layui-code" skin="notepad">package view;

import java.awt.AWTEvent;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URL;
import java.net.URLClassLoader;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JToolBar;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.plaf.basic.BasicBorders;

public class ResearchMain extends JFrame implements ActionListener{
	//框架大小
	Dimension faceSize=new Dimension(950, 650);
	Image icon;
	ImageIcon banner;
	//程序图标
	JPanel panel1;
	JLabel jLabel;

	JMenuBar menuBar;
	
	JMenu menu1;
	JMenu menu2;
	JMenu menu3;
	JMenu menu4;
	JMenu menu5;
	
	JMenuItem item1;
	JMenuItem item2;
	JMenuItem item3;
	JMenuItem item4;
	JMenuItem item5;
	JMenuItem item6;
	JMenuItem item7;
	JMenuItem item8;
	JMenuItem item9;
	JMenuItem item10;
	
	//boolean packFame=false;
	public ResearchMain() {
		this.setLayout(new BorderLayout());//边框布局
		enableEvents(AWTEvent.WINDOW_EVENT_MASK);
		//添加框架的关闭时间处理2
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		//窗口自适应大小 使窗体能正好显示里面的所有控件
		this.pack();
		//设置框架的大小
		this.setSize(faceSize);
		//设置窗体的标题
		this.setTitle("科研信息管理系统");
		//调用自定义的方法GetImage（） ，获取图标文件
		icon=getImage("icon.png");
		//设置窗体图标
		this.setIconImage(icon);
		//设置不能调整窗体的大小
		this.setResizable(false);
		//获取屏幕大小
		Dimension screenSize=Toolkit.getDefaultToolkit().getScreenSize();
		//获取当前项目的窗体大小
		Dimension frameSize=this.getSize();
		//如果项目窗体高&amp;gt;屏幕高，用屏幕高设置项目窗体高
		if (frameSize.height&amp;gt;screenSize.height) {
			frameSize.height=screenSize.height;
		}
		if (frameSize.width&amp;gt;screenSize.width) {
			frameSize.width=screenSize.width;
		}
		//设置窗体起始显示位置 居中显示
		this.setLocation((screenSize.width-frameSize.width)/2,
		(screenSize.height-frameSize.height)/2);
		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (ClassNotFoundException | InstantiationException | IllegalAccessException
				| UnsupportedLookAndFeelException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		try {
			bt();//初始化标题栏
			gj();//工具栏
			tp();//图片
			addListener();//监听
			this.setVisible(true);
	
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}		
		
	}
	public void bt() {
		menuBar=new JMenuBar();
		this.setJMenuBar(menuBar);
		menu1=new JMenu("系统设置");
		menuBar.add(menu1);
		menu2=new JMenu("论文信息管理");
		menuBar.add(menu2);
		menu3=new JMenu("教师信息管理");
		menuBar.add(menu3);
		menu4=new JMenu("部门信息管理");
		menuBar.add(menu4);
		menu5=new JMenu("帮助");
		menuBar.add(menu5);
		item1=new JMenuItem("用户管理");
		item2=new JMenuItem("退出系统");
		menu1.add(item1);
		menu1.add(item2);
		item3=new JMenuItem("论文信息管理");
		item4=new JMenuItem("论文信息查询");
		menu2.add(item3);
		menu2.add(item4);
		item5=new JMenuItem("教师基本信息管理");
		item6=new JMenuItem("教师基本信息查询");
		menu3.add(item5);
		menu3.add(item6);
		item7=new JMenuItem("部门基本信息管理");
		item8=new JMenuItem("部门基本信息查询");
		menu4.add(item7);
		menu4.add(item8);
		item9=new JMenuItem("帮助");
		item10=new JMenuItem("关于");
		menu5.add(item9);
		menu5.add(item10);
		menuBar.setVisible(true);
		
	}
	public void gj() {
		JToolBar toolBar = new JToolBar(); 
		JButton ambtn,asbtn,tmbtn,dmbtn,help,about; 
		ambtn=new JButton(new ImageIcon("res/card.png"));
		asbtn=new JButton(new ImageIcon("res/folder.png"));
		tmbtn=new JButton(new ImageIcon("res/info.png"));
		dmbtn=new JButton(new ImageIcon("res/save.png"));
		help=new JButton(new ImageIcon("res/help.png"));
		about=new JButton(new ImageIcon("res/user.png"));
		toolBar.add(ambtn);
		toolBar.add(asbtn);
		toolBar.add(tmbtn);
		toolBar.add(dmbtn);
		toolBar.add(help);
		toolBar.add(about);
		this.add(toolBar,BorderLayout.NORTH);
	}
	public void tp() {
		banner=new ImageIcon("res/image.png");
		jLabel=new JLabel(banner);
		panel1=new JPanel();
		panel1.add(jLabel);
		this.add(panel1,BorderLayout.CENTER);
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		new ResearchMain();
		
	}

	/** * 通过给定的文件名获得图像 */
	
	Image getImage(String filename){ 
		//URLClassLoader--用于从指向 jar文件和目录的 URL 的搜索路径加载类和资源。
		URLClassLoader urlLoader=(URLClassLoader) this.getClass().getClassLoader(); 
		
		URL url=null; 
		Image image=null;
		url=urlLoader.findResource(filename); 
		image=Toolkit.getDefaultToolkit().getImage(url); 
		MediaTracker mediaTracker=new MediaTracker(this); 
		 try { 
			 mediaTracker.addImage(image, 0); 
			 mediaTracker.waitForID(0); 
		 }catch (InterruptedException _ex){
			 image=null;
		 }
		 if (mediaTracker.isErrorID(0)) {
			 image=null;
		 }
		 return image;
	}
	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		Object obj=e.getSource();
		if (obj==item2) {
			System.exit(0);
		}
		
	}
	public void addListener() {
		item2.addActionListener(this);
	}
	
}
&lt;/pre></description></item><item><title>eclipse快速生成set get方法以及构造方法</title><link>https://pangyd.com/post/63-eclipseset-get/</link><pubDate>Thu, 17 Aug 2017 16:59:13 +0800</pubDate><guid>https://pangyd.com/post/63-eclipseset-get/</guid><description>&lt;p style="text-align: center">在eclipse中按快捷键 &amp;nbsp;alt&amp;nbsp;+ shift + s &amp;nbsp;选择generate constructor using fields。然后在弹出框中选择成员变量 即可快速创建构造方法。&amp;nbsp;&lt;/p>&lt;p style="text-align: center">&lt;a target="_blank" href="https://gss0.baidu.com/9fo3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item/83025aafa40f4bfb2959b0fe064f78f0f636188a.jpg" title="点击查看大图" class="ikqb_img_alink" rel="nofollow">&lt;img class="ikqb_img" src="https://pangyd.com/uploads/2017/08/fdc5ddc2a17ac054.jpg" alt="">&lt;/a>&lt;/p>&lt;p style="text-align: center">生成set get方法：&lt;/p>&lt;p style="text-align: center">在合适的地方采用快捷键 Shift+Alt+S&amp;nbsp;&lt;br>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" alt="">&lt;br>选择红框中的Generate Getter and Setter再选择需要实现get、set的参数&lt;br>&lt;img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='120'%3E%3Crect width='480' height='120' fill='%230E1012' stroke='%231B1E22'/%3E%3Ctext x='240' y='66' fill='%235C6069' font-family='monospace' font-size='13' text-anchor='middle'%3E%5B%E5%8E%9F%E5%9B%BE%E5%B7%B2%E5%A4%B1%E6%95%88%5D%3C/text%3E%3C/svg%3E" alt="">&lt;/p></description></item><item><title>eclipse快捷键大全</title><link>https://pangyd.com/post/62-eclipse/</link><pubDate>Wed, 16 Aug 2017 20:21:43 +0800</pubDate><guid>https://pangyd.com/post/62-eclipse/</guid><description>&lt;p>&lt;strong>1 几个最重要的快捷键&lt;/strong>&lt;/p>&lt;p>代码助手:Ctrl+Space（简体中文操作系统是Alt+/）&lt;br>快速修正：Ctrl+1&lt;br>单词补全：Alt+/&lt;br>打开外部Java文档：Shift+F2&lt;/p>&lt;p>显示搜索对话框：Ctrl+H&lt;br>快速Outline：Ctrl+O&lt;br>打开资源：Ctrl+Shift+R&lt;br>打开类型：Ctrl+Shift+T&lt;br>显示重构菜单：Alt+Shift+T&lt;/p>&lt;p>上一个/下一个光标的位置：Alt+Left/Right&amp;nbsp;&lt;br>上一个/下一个成员（成员对象或成员函数）：Ctrl+Shift+Up/Down&lt;br>选中闭合元素：Alt+Shift+Up/Down/Left/Right&lt;br>删除行：Ctrl+D&lt;br>在当前行上插入一行：Ctrl+Shift+Enter&lt;br>在当前行下插入一行： Shift+Enter&lt;br>上下移动选中的行：Alt+Up/Down&lt;/p>&lt;p>组织导入：Ctrl+Shift+O&lt;/p>&lt;p>&lt;strong>2 定位&lt;/strong>&lt;/p>&lt;p>2.1 行内定位&lt;/p>&lt;p>行末/行首：End/Home&lt;br>前一个/后一个单词：Ctrl+Right/Left&lt;/p>&lt;p>2.2 文件内定位&lt;/p>&lt;p>跳到某行：Ctrl+L&lt;br>上下滚屏：Ctrl+Up/Down&lt;br>上一个/下一个成员（成员对象或成员函数）：Ctrl+Shift+Up/Down&lt;br>快速Outline：Ctrl+O&lt;/p>&lt;p>2.3 跨文件定位&lt;/p>&lt;p>打开声明：F3&lt;br>打开资源：Ctrl+Shift+R&lt;br>打开类型：Ctrl+Shift+T&lt;br>在workspace中搜索选中元素的声明：Ctrl+G&lt;br>在workspace中搜索选中的文本：Ctrl+Alt+G&lt;br>在workspace中搜索选中元素的引用：Ctrl+Shift+G&lt;br>打开调用层次结构：Ctrl+Alt+H&lt;br>快速层次结构：Ctrl+T&lt;br>反悔：Ctrl+Z&lt;/p>&lt;p>2.4 其它&lt;/p>&lt;p>上一个/下一个光标所在位置：Alt+Left/Right&lt;br>上一个编辑的位置：Ctrl+Q&lt;/p>&lt;p>&lt;strong>3 选中&lt;/strong>&lt;/p>&lt;p>3.1 行内选中&lt;/p>&lt;p>选中到行末/行首：Shift+End/Home&lt;br>选中上一个/下一个单词：Ctrl+Shift+Left/Right&lt;/p>&lt;p>3.2 文件内选中&lt;/p>&lt;p>选中闭合元素：Alt+Shift+Up&lt;br>恢复到上一个选中：Alt+Shift+Down&lt;br>选中下一个/上一个元素：Alt+Shift+Right/Left&lt;/p>&lt;p>&lt;strong>4 定位/选中/操作同时&lt;/strong>&lt;/p>&lt;p>删除行：Ctrl+D&lt;br>删除下一个/上一个单词：Ctrl+Delete/Backspace&lt;br>删除到行末：Ctrl+Shift+Delete&lt;br>在当前行上插入一行：Ctrl+Shift+Enter&amp;nbsp;&lt;br>在当前行下插入一行： Shift+Enter&lt;br>上下移动选中的行：Alt+Up/Down&lt;br>拷贝选中的行：Ctrl+Alt+Up/Down&lt;/p>&lt;p>&lt;strong>5 其它的代码编辑类快捷键&lt;/strong>&lt;/p>&lt;p>保存：Ctrl+S&lt;br>保存所有：Ctrl+Shift+S&lt;br>下一个命中的项（搜索之后）：Ctrl+.&lt;br>注释：Ctrl+/&lt;br>添加导入：Ctrl+Shift+M&lt;br>显示快捷键帮助：Ctrl+Shift+L&lt;br>变为大/小写：Ctrl+Shift+X/Y&lt;/p>&lt;p>&lt;strong>6 重构&lt;/strong>&lt;/p>&lt;p>显示重构菜单：Alt+Shift+T&lt;br>重构-改变方法签名：Alt+Shift+C&lt;br>重构-移动：Alt+Shift+V&lt;br>重构-重命名：Alt+Shift+R&lt;/p>&lt;p>&lt;strong>7 编辑器、视图、透视图切换&lt;/strong>&lt;/p>&lt;p>下一个编辑器：Ctrl+F6&lt;br>下一个视图：Ctrl+F7&lt;br>下一个透视图：Ctrl+F8&lt;br>最大化当前视图或编辑器：Ctrl+M&lt;br>激活编辑器：F12&lt;/p>&lt;p>&lt;strong>8 Debug&lt;/strong>&lt;/p>&lt;p>F5：Step Into（debug）&lt;br>F6：Step over（debug）&lt;br>F7：Step return（debug）&lt;br>F8：Resume（debug）&lt;br>F11：debug上一个应用（debug）&lt;/p>&lt;p>&lt;strong>9 Up/Down/Right/Left类快捷键&lt;/strong>&lt;/p>&lt;p>Ctrl&lt;br>前一个/后一个单词：Ctrl+Right/Left&lt;br>上下滚屏：Ctrl+Up/Down&lt;/p>&lt;p>Alt&lt;br>上一个/下一个光标的位置：Alt+Left/Right&lt;br>上下移动选中的行：Alt+Up/Down&lt;br>Shift&lt;br>选中上一个/下一个字符：Shift+Left/Right&lt;br>选中上一行/下一行（从当前光标位置开始）：Shift+Up/Down&lt;/p>&lt;p>Ctrl+Shift&lt;br>上一个/下一个成员（成员对象或成员函数）：Ctrl+Shift+Up/Down&lt;br>选中上一个/下一个单词：Ctrl+Shift+Left/Right&lt;/p>&lt;p>Alt+Shift&lt;br>选中闭合元素：Alt+Shift+Up&lt;br>恢复到上一个选中：Alt+Shift+Down&lt;br>选中下一个/上一个元素：Alt+Shift+Right/Left&lt;br>拷贝选中的行：Ctrl+Alt+Up/Down&lt;/p>&lt;p>Ctrl+Alt&lt;br>拷贝选中的行：Ctrl+Alt+Up/Down&lt;/p>&lt;p>&lt;strong>10 F类快捷键&lt;/strong>&lt;/p>&lt;p>F2：显示提示/重命名&lt;br>F3：打开选中元素的声明&lt;br>F4：打开选中元素的类型继承结构&lt;br>F5：刷新&lt;br>F5：Step Into（debug）&lt;br>F6：Step over（debug）&lt;br>F7：Step return（debug）&lt;br>F8：Resume（debug）&lt;br>F11：debug上一个应用（debug）&lt;br>F12：激活编辑器&lt;/p>&lt;p>&lt;strong>补充：&lt;/strong>&lt;/p>&lt;p>Ctrl+1 快速修复(最经典的快捷键,就不用多说了)&lt;br>Ctrl+D: 删除当前行&amp;nbsp;&lt;br>Ctrl+Alt+↓ 复制当前行到下一行(复制增加)&lt;br>Ctrl+Alt+↑ 复制当前行到上一行(复制增加)&lt;br>Alt+↓ 当前行和下面一行交互位置(特别实用,可以省去先剪切,再粘贴了)&lt;br>Alt+↑ 当前行和上面一行交互位置(同上)&lt;br>Alt+← 前一个编辑的页面&lt;br>Alt+→ 下一个编辑的页面(当然是针对上面那条来说了)&lt;br>Alt+Enter 显示当前选择资源(工程,or 文件 or文件)的属性&lt;br>Shift+Enter 在当前行的下一行插入空行(这时鼠标可以在当前行的任一位置,不一定是最后)&lt;br>Shift+Ctrl+Enter 在当前行插入空行(原理同上条)&lt;br>Ctrl+Q 定位到最后编辑的地方&lt;br>Ctrl+L 定位在某行 (对于程序超过100的人就有福音了)&lt;br>Ctrl+M 最大化当前的Edit或View (再按则反之)&lt;br>Ctrl+/ 注释当前行,再按则取消注释&lt;br>Ctrl+O 快速显示 OutLine&lt;br>Ctrl+T 快速显示当前类的继承结构&lt;br>Ctrl+W 关闭当前Editer&lt;br>Ctrl+K 参照选中的Word快速定位到下一个&lt;br>Ctrl+E 快速显示当前Editer的下拉列表(如果当前页面没有显示的用黑体表示)&lt;br>Ctrl+/(小键盘) 折叠当前类中的所有代码&lt;br>Ctrl+×(小键盘) 展开当前类中的所有代码&lt;br>Ctrl+Space 代码助手完成一些代码的插入(但一般和输入法有冲突,可以修改输入法的热键,也可以暂用Alt+/来代替)&lt;br>Ctrl+Shift+E 显示管理当前打开的所有的View的管理器(可以选择关闭,激活等操作)&lt;br>Ctrl+J 正向增量查找(按下Ctrl+J后,你所输入的每个字母编辑器都提供快速匹配定位到某个单词,如果没有,则在stutes line中显示没有找到了,查一个单词时,特别实用,这个功能Idea两年前就有了)&lt;br>Ctrl+Shift+J 反向增量查找(和上条相同,只不过是从后往前查)&lt;br>Ctrl+Shift+F4 关闭所有打开的Editer&lt;br>Ctrl+Shift+X 把当前选中的文本全部变味小写&lt;br>Ctrl+Shift+Y 把当前选中的文本全部变为小写&lt;br>Ctrl+Shift+F 格式化当前代码&lt;br>Ctrl+Shift+P 定位到对于的匹配符(譬如{}) (从前面定位后面时,光标要在匹配符里面,后面到前面,则反之)&lt;/p></description></item><item><title>MySQL多关键字多字段模糊查询</title><link>https://pangyd.com/post/61-mysql/</link><pubDate>Wed, 16 Aug 2017 20:18:48 +0800</pubDate><guid>https://pangyd.com/post/61-mysql/</guid><description>&lt;pre lay-lang="Java" class="layui-code" skin="notepad">sql="select *,teacher.teacherID as teacherName, "
					+ "department.depID as depName "
					+ "from teacher,article,department "
					+ "where teacher.teacherID=article.teacherID and department.depID=article.depID and articleName like '%"+f2+"%' "//查询关键字
					+ "and teacherName like '%"+f3+"%' "
					+ "and year like '%"+f6+"%' "
					+ "and depName like '%"+f9+"%' "
					+ "order by articleID";&lt;/pre></description></item><item><title>Java判断两个汉字是否相等</title><link>https://pangyd.com/post/60-java/</link><pubDate>Tue, 15 Aug 2017 19:01:04 +0800</pubDate><guid>https://pangyd.com/post/60-java/</guid><description>&lt;p style="text-align: center">&lt;b>今天试了下用if语句判断两个汉字是否相等 结果两个相等的汉字也会else 从网上查了查用下面语句不会出错：&lt;/b>&lt;/p>&lt;p>&lt;p style="text-align: center">&lt;b>&amp;nbsp;String&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;str1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;=&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;new&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;String("");&amp;nbsp;&lt;br>&amp;nbsp;String&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;str2&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;=&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;new&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;String("");&amp;nbsp;&lt;br>&amp;nbsp; str1.equals(str2)(相等时为true)&amp;nbsp;&lt;br>或str1.compareTo(str2)（只有在.equals()返回true时才为0）&amp;nbsp;&lt;/b>&lt;/p>&lt;/p></description></item><item><title>科研信息管理系统---论文信息管理（及修改，删除，增加，查询为一体）</title><link>https://pangyd.com/post/59/</link><pubDate>Tue, 15 Aug 2017 18:59:24 +0800</pubDate><guid>https://pangyd.com/post/59/</guid><description>&lt;pre lay-lang="Java" class="layui-code" skin="notepad">	package com.jnzyjsxy.node1;

	import java.awt.BorderLayout;
	import java.awt.Dimension;
	import java.awt.Font;
	import java.awt.GridBagConstraints;
	import java.awt.GridBagLayout;
	import java.awt.Insets;
	import java.awt.event.ActionEvent;
	import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
	import javax.swing.JOptionPane;
	import javax.swing.JPanel;
	import javax.swing.JScrollPane;
	import javax.swing.JTable;
	import javax.swing.JTextField;
	import javax.swing.ListSelectionModel;
	import javax.swing.event.ListSelectionEvent;
	import javax.swing.event.ListSelectionListener;

import com.jnzyjsxy.common.ArticleBean;
import com.jnzyjsxy.common.Department;
import com.jnzyjsxy.common.TeacherBean;
//import com.jnzyjsxy.common.HistrinBeanb;
	//import com.jnzyjsxy.common.PersonBean;
	import com.jnzyjsxy.test.KyMain;
import com.jnzyjsxy.test.text;

	/*
	 * 人员删除管理
	 */
	public class Node11Panel extends JPanel implements ListSelectionListener,ActionListener,ItemListener{

		//创建上中下面板
		JPanel upPanel =new JPanel();
		JPanel centerPanel=new JPanel();
		JPanel downpanel =new JPanel();
		//定义图形界面元素
		String DeptID="1";//部门编号
		String teacher="1";
		JComboBox jComboBox11=null;//显示人员所在部门
		JComboBox jComboBox12=null;//显示人员所在部门
		JLabel jLabel=new JLabel();
		JLabel jLabel1=new JLabel();
		JLabel jLabel2=new JLabel();
		JLabel jLabel3=new JLabel();
		JLabel jLabel4=new JLabel();
		JLabel jLabel5=new JLabel();
		JLabel jLabel6=new JLabel();
		JLabel jLabel7=new JLabel();
		JLabel jLabel8=new JLabel();
		JLabel jLabel9=new JLabel();
		JLabel jLabel10=new JLabel();
		JLabel jLabel11=new JLabel();
		//JLabel jLabel3=new JLabel();
		
		JTextField jTextField1=new JTextField(15);
		JTextField jTextField2=new JTextField(15);
		JTextField jTextField3=new JTextField(15);
		JTextField jTextField4=new JTextField(15);
		JTextField jTextField5=new JTextField(15);
		JTextField jTextField6=new JTextField(15);
		JTextField jTextField7=new JTextField(15);
		JTextField jTextField8=new JTextField(15);
		JTextField jTextField9=new JTextField(15);
		JTextField jTextField10=new JTextField(15);
		JTextField jTextField11=new JTextField(15);
		
		JButton hq=new JButton();
		JButton addInfo=new JButton();
		JButton modifyInfo=new JButton();
		JButton deleteInfo=new JButton();
		JButton clearInfo=new JButton();
		
		
		JScrollPane jScrollPane1;
		JScrollPane jScrollPane2;
		
		//创建网格包布局对象
		GridBagLayout girdBag=new GridBagLayout();
		//创建网格包约束类变量
		GridBagConstraints girdBagCon;
		
		//定义表格变量
		JTable jTable;
		//ListSelectionModel列表选中模式类 用于设置JTable中记录选中的模式
		ListSelectionModel ListSelectionModel=null;
		//字符数组 存储列明 对应person 列名
		String[] colName={"编号","题目","作者","期刊/出版社","级别","发表时间","第几期","字数","部门编号","统计日期","备注"};
		//二维数组 存储每一行的记录纸行存储记录编号 列存储该记录各列值
		String[][] colValue;
		GridBagLayout girBag =new GridBagLayout();
		GridBagConstraints gridBagCon;
		
		
		//构造方法
		public Node11Panel() {
			// TODO Auto-generated constructor stub
			this.setLayout(new BorderLayout());//边框布局
			try {
				upInit();//上
				centenInit();
				//panelInit panelInit=new panelInit();
				//this.add(panelInit,BorderLayout.CENTER);//中
				//downInit();//下
				addListener();//监听
			} catch (Exception e) {
				// TODO: handle exception
				e.printStackTrace();
			}
		}
		//上布局
		public void upInit() {
			//创建人员数据操作类 以便调用该类方法
			ArticleBean bean=new ArticleBean();
			//上部采用网格包不几乎 放置人员信息删除标签和包含表格的滚动面板
			upPanel.setLayout(girBag);
			try {
				//在上部添加标签 
				jLabel.setText("论文信息管理");
				jLabel.setFont(new Font("Dialog", 0, 16));
				gridBagCon=new GridBagConstraints();
				gridBagCon.gridx=0;
				gridBagCon.gridy=0;
				//外部填充 4个参数 top,left,bottom,right
				//既外部间距
				gridBagCon.insets=new Insets(0, 10, 0, 10);
				girBag.setConstraints(jLabel, gridBagCon);
				upPanel.add(jLabel);
				
				//调用Person类的searchAll 方法 获取所有的人员记录
				colValue=bean.searchAllForNode();
				//初始化表对象 2个参数 下面是JTable的构造
				//JTable(Object[][] rowData, Object[] columnNames) 
				 // 构造一个 JTable 来显示二维数组 rowData 中的值，其列名称为 columnNames
				//即第1个参数二维数组存储每一行的值，第2个参数一维数组存放列名称 
				jTable=new JTable(colValue,colName);
				//设置表的大小
				jTable.setPreferredScrollableViewportSize(new Dimension(750,350));
				//初始化表格选择模式对象
				ListSelectionModel=jTable.getSelectionModel();
				//设置表格为单选模式
				ListSelectionModel.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
				//添加选择监听事件
				ListSelectionModel.addListSelectionListener(this);
				//把表格放进滚动栏 
				jScrollPane1=new JScrollPane(jTable);
				//设置滚动面板大小
				jScrollPane1.setPreferredSize(new Dimension(750, 350));
				//把滚动面板放在标签的下面
				gridBagCon=new GridBagConstraints();
				gridBagCon.gridx=0;
				gridBagCon.gridy=1;
				gridBagCon.insets=new Insets(0, 0, 0, 0);
				girBag.setConstraints(jScrollPane1, gridBagCon);
				upPanel.add(jScrollPane1);
			} catch (Exception e) {
				// TODO: handle exception
				e.printStackTrace();
			}
			//添加上部面板
			this.add(upPanel,BorderLayout.NORTH);
		}
		//中部面板
		
		public void centenInit() throws Exception{
			//中间放组件的面板 采用网格包布局
			centerPanel.setLayout(girdBag);
			//第一行组件
			//griy=1 实际的第二行 显示4个组件 gridx依次增加
			jLabel1.setText("论文编号");
			jLabel1.setFont(new Font("Dialog", 0, 12));
			girdBagCon=new GridBagConstraints();
			girdBagCon.gridx=0;
			girdBagCon.gridy=1;
			//外部填充 4个参数 top,left,bottom,right
			//既外部间距
			girdBagCon.insets=new Insets(0, 10, 10, 1);
			girdBag.setConstraints(jLabel1, girdBagCon);
			centerPanel.add(jLabel1);
			
			girdBagCon=new GridBagConstraints();
			girdBagCon.gridx=1;
			girdBagCon.gridy=1;
			girdBagCon.insets=new Insets(0, 1, 10, 15);
			girdBag.setConstraints(jTextField1, girdBagCon);
			centerPanel.add(jTextField1);
			
			jLabel2.setText("论文题目");
			jLabel2.setFont(new Font("Dialog", 0, 12));
			girdBagCon=new GridBagConstraints();
			girdBagCon.gridx=2;
			girdBagCon.gridy=1;
			//外部填充 4个参数 top,left,bottom,right
			//既外部间距
			girdBagCon.insets=new Insets(0, 15, 10, 1);
			girdBag.setConstraints(jLabel2, girdBagCon);
			centerPanel.add(jLabel2);
			
			girdBagCon=new GridBagConstraints();
			girdBagCon.gridx=3;
			girdBagCon.gridy=1;
			girdBagCon.insets=new Insets(0, 1, 10, 10);
			girdBag.setConstraints(jTextField2, girdBagCon);
			centerPanel.add(jTextField2);
			
			jLabel3.setText("作者");
			jLabel3.setFont(new Font("Dialog", 0, 12));
			girdBagCon=new GridBagConstraints();
			girdBagCon.gridx=4;
			girdBagCon.gridy=1;
			//外部填充 4个参数 top,left,bottom,right
			//既外部间距
			girdBagCon.insets=new Insets(10, 10, 10, 1);
			girdBag.setConstraints(jLabel3, girdBagCon);
			centerPanel.add(jLabel3);
			
			TeacherBean teacherBean=new TeacherBean();
			String[] alltype=teacherBean.searchAllForNode();
			//jComboBox11.setPreferredSize(new Dimension(125, 25));
			jComboBox11=new JComboBox(alltype);
			
			
			girdBagCon=new GridBagConstraints();
			girdBagCon.gridx=5;
			girdBagCon.gridy=1;
			girdBagCon.insets=new Insets(10, 1, 10, 15);
			girdBag.setConstraints(jComboBox11, girdBagCon);
			centerPanel.add(jComboBox11);
			
			jLabel4.setText("期刊名称");
			jLabel4.setFont(new Font("Dialog", 0, 12));
			girdBagCon=new GridBagConstraints();
			girdBagCon.gridx=0;
			girdBagCon.gridy=2;
			//外部填充 4个参数 top,left,bottom,right
			//既外部间距
			girdBagCon.insets=new Insets(10, 15, 10, 1);
			girdBag.setConstraints(jLabel4, girdBagCon);
			centerPanel.add(jLabel4);
			
			girdBagCon=new GridBagConstraints();
			girdBagCon.gridx=1;
			girdBagCon.gridy=2;
			girdBagCon.insets=new Insets(10, 1, 10, 10);
			girdBag.setConstraints(jTextField4, girdBagCon);
			centerPanel.add(jTextField4);
			
			jLabel5.setText("级别");
			jLabel5.setFont(new Font("Dialog", 0, 12));
			girdBagCon=new GridBagConstraints();
			girdBagCon.gridx=2;
			girdBagCon.gridy=2;
			//外部填充 4个参数 top,left,bottom,right
			//既外部间距
			girdBagCon.insets=new Insets(10, 10, 10, 1);
			girdBag.setConstraints(jLabel5, girdBagCon);
			centerPanel.add(jLabel5);
			
			girdBagCon=new GridBagConstraints();
			girdBagCon.gridx=3;
			girdBagCon.gridy=2;
			girdBagCon.insets=new Insets(10, 1, 10, 15);
			girdBag.setConstraints(jTextField5, girdBagCon);
			centerPanel.add(jTextField5);
			
			jLabel6.setText("发表年份");
			jLabel6.setFont(new Font("Dialog", 0, 12));
			girdBagCon=new GridBagConstraints();
			girdBagCon.gridx=4;
			girdBagCon.gridy=2;
			//外部填充 4个参数 top,left,bottom,right
			//既外部间距
			girdBagCon.insets=new Insets(10, 15, 10, 1);
			girdBag.setConstraints(jLabel6, girdBagCon);
			centerPanel.add(jLabel6);
			
			girdBagCon=new GridBagConstraints();
			girdBagCon.gridx=5;
			girdBagCon.gridy=2;
			girdBagCon.insets=new Insets(10, 1, 10, 10);
			girdBag.setConstraints(jTextField6, girdBagCon);
			centerPanel.add(jTextField6);
			
			//第四行显示组件 gridy=4 gridx 依次增加
			jLabel7.setText("刊期");
			jLabel7.setFont(new Font("Dialog", 0, 12));
			girdBagCon=new GridBagConstraints();
			girdBagCon.gridx=0;
			girdBagCon.gridy=3;
			//外部填充 4个参数 top,left,bottom,right
			//既外部间距
			girdBagCon.insets=new Insets(10, 10, 10, 1);
			girdBag.setConstraints(jLabel7, girdBagCon);
			centerPanel.add(jLabel7);
			
			girdBagCon=new GridBagConstraints();
			girdBagCon.gridx=1;
			girdBagCon.gridy=3;
			girdBagCon.insets=new Insets(10, 1, 10, 10);
			girdBag.setConstraints(jTextField7, girdBagCon);
			centerPanel.add(jTextField7);
			
			jLabel8.setText("字数");
			jLabel8.setFont(new Font("Dialog", 0, 12));
			girdBagCon=new GridBagConstraints();
			girdBagCon.gridx=2;
			girdBagCon.gridy=3;
			//外部填充 4个参数 top,left,bottom,right
			//既外部间距
			girdBagCon.insets=new Insets(10, 10, 10, 1);
			girdBag.setConstraints(jLabel8, girdBagCon);
			centerPanel.add(jLabel8);
			
			girdBagCon=new GridBagConstraints();
			girdBagCon.gridx=3;
			girdBagCon.gridy=3;
			girdBagCon.insets=new Insets(10, 1, 10, 10);
			girdBag.setConstraints(jTextField8, girdBagCon);
			centerPanel.add(jTextField8);
			
			jLabel9.setText("所在系部");
			jLabel9.setFont(new Font("Dialog", 0, 12));
			girdBagCon=new GridBagConstraints();
			girdBagCon.gridx=4;
			girdBagCon.gridy=3;
			//外部填充 4个参数 top,left,bottom,right
			//既外部间距
			girdBagCon.insets=new Insets(10, 10, 10, 1);
			girdBag.setConstraints(jLabel9, girdBagCon);
			centerPanel.add(jLabel9);
			
			Department department=new Department();
			String[] s=department.searchAllForNode();
			//jComboBox12.setPreferredSize(new Dimension(125, 25));
			jComboBox12=new JComboBox(s);
			
			girdBagCon=new GridBagConstraints();
			girdBagCon.gridx=5;
			girdBagCon.gridy=3;
			girdBagCon.insets=new Insets(10, 1, 10, 10);
			girdBag.setConstraints(jComboBox12, girdBagCon);
			centerPanel.add(jComboBox12);
			
			jLabel10.setText("录入日期");
			jLabel10.setFont(new Font("Dialog", 0, 12));
			girdBagCon=new GridBagConstraints();
			girdBagCon.gridx=0;
			girdBagCon.gridy=4;
			//外部填充 4个参数 top,left,bottom,right
			//既外部间距
			girdBagCon.insets=new Insets(10, 10, 10, 1);
			girdBag.setConstraints(jLabel10, girdBagCon);
			centerPanel.add(jLabel10);
			
			girdBagCon=new GridBagConstraints();
			girdBagCon.gridx=1;
			girdBagCon.gridy=4;
			girdBagCon.insets=new Insets(10, 1, 10, 10);
			girdBag.setConstraints(jTextField10, girdBagCon);
			centerPanel.add(jTextField10);
			
			
			jLabel11.setText("备注");
			jLabel11.setFont(new Font("Dialog", 0, 12));
			girdBagCon=new GridBagConstraints();
			girdBagCon.gridx=2;
			girdBagCon.gridy=4;
			//外部填充 4个参数 top,left,bottom,right
			//既外部间距
			girdBagCon.insets=new Insets(10, 10, 10, 1);
			girdBag.setConstraints(jLabel11, girdBagCon);
			centerPanel.add(jLabel11);
			
			girdBagCon=new GridBagConstraints();
			girdBagCon.gridx=3;
			girdBagCon.gridy=4;
			girdBagCon.insets=new Insets(10, 1, 10, 10);
			girdBag.setConstraints(jTextField11, girdBagCon);
			centerPanel.add(jTextField11);
			
			
			//定义部门操作类
			//DeptBean dBean=new DeptBean();
			//调用方法获取所有部门的字符串
			//String[] alltype=dBean.searchAllForNode();
			//jComboBox1=new JComboBox(alltype);
			
			//girdBagCon=new GridBagConstraints();
			//girdBagCon.gridx=1;
			//girdBagCon.gridy=4;
			//girdBagCon.gridwidth=3;
			//girdBagCon.gridheight=1;
			//girdBagCon.insets=new Insets(10, 1, 10, 15);
			//girdBag.setConstraints(jComboBox1, girdBagCon);
			//centerPanel.add(jComboBox1);
						
			hq.setText("获取新编号");
			hq.setFont(new Font("Dialog", 0, 12));
			girdBagCon=new GridBagConstraints();
			girdBagCon.gridx=0;
			girdBagCon.gridy=5;
			girdBagCon.gridwidth=2;
			girdBagCon.gridheight=1;
			//外部填充 4个参数 top,left,bottom,right
			//既外部间距
			girdBagCon.insets=new Insets(10, 10, 10, 10);
			girdBag.setConstraints(hq, girdBagCon);
			centerPanel.add(hq);
			
			addInfo.setText("增加");
			addInfo.setFont(new Font("Dialog", 0, 12));
			girdBagCon=new GridBagConstraints();
			girdBagCon.gridx=1;
			girdBagCon.gridy=5;
			girdBagCon.gridwidth=2;
			girdBagCon.gridheight=1;
			//外部填充 4个参数 top,left,bottom,right
			//既外部间距
			girdBagCon.insets=new Insets(10, 10, 10, -100);
			girdBag.setConstraints(addInfo, girdBagCon);
			centerPanel.add(addInfo);
			
			modifyInfo.setText("修改");
			modifyInfo.setFont(new Font("Dialog", 0, 12));
			girdBagCon=new GridBagConstraints();
			girdBagCon.gridx=2;
			girdBagCon.gridy=5;
			//girdBagCon.gridwidth=2;
			//girdBagCon.gridheight=1;
			//外部填充 4个参数 top,left,bottom,right
			//既外部间距
			girdBagCon.insets=new Insets(10, 10, 10, -150);
			girdBag.setConstraints(modifyInfo, girdBagCon);
			centerPanel.add(modifyInfo);
			
			deleteInfo.setText("删除");
			deleteInfo.setFont(new Font("Dialog", 0, 12));
			girdBagCon=new GridBagConstraints();
			girdBagCon.gridx=3;
			girdBagCon.gridy=5;
			//girdBagCon.gridwidth=2;
			//girdBagCon.gridheight=1;
			//外部填充 4个参数 top,left,bottom,right
			//既外部间距
			girdBagCon.insets=new Insets(10, 10, 10, -150);
			girdBag.setConstraints(deleteInfo, girdBagCon);
			centerPanel.add(deleteInfo);
			
			deleteInfo.addActionListener((ActionListener) this);
			
			
			clearInfo.setText("清空");
			clearInfo.setFont(new Font("Dialog", 0, 12));
			girdBagCon=new GridBagConstraints();
			girdBagCon.gridx=4;
			girdBagCon.gridy=5;
			//girdBagCon.gridwidth=2;
			//girdBagCon.gridheight=1;
			//外部填充 4个参数 top,left,bottom,right
			//既外部间距
			girdBagCon.insets=new Insets(10, 10, 10, -170);
			girdBag.setConstraints(clearInfo, girdBagCon);
			centerPanel.add(clearInfo);
			this.add(centerPanel,BorderLayout.CENTER);

			jTextField1.setEditable(false);
			deleteInfo.setEnabled(false);
			modifyInfo.setEnabled(false);
			addInfo.setEnabled(false);
		}
		
		public void addListener() throws Exception{
			//删除按钮 活动监听
			deleteInfo.addActionListener(this);
			hq.addActionListener(this);
			addInfo.addActionListener(this);
			modifyInfo.addActionListener(this);
			clearInfo.addActionListener(this);
			jComboBox11.addItemListener(this);
			jComboBox12.addItemListener(new ItemListener() {
				
				@Override
				public void itemStateChanged(ItemEvent e) {
					// TODO Auto-generated method stub
					if (e.getStateChange()==ItemEvent.SELECTED)
					{
						//获取选中项目值，得到的是一个“1-办公室-秘书室”这样的字符串 
						//字符串构成：部门编号-一级部门-二级部门 
						System.out.println("321");
						String temStr=""+e.getItem();
						//返回指定子字符串"-"在此字符串中第一次出现处的索引 
						int i=temStr.indexOf("-");
						 //取部门id子字符串，目的是取前面的部门编号 
						DeptID=temStr.substring(0,i);
					}
					
				}
			});
		}
		public void actionPerformed(ActionEvent e) {
			// TODO Auto-generated method stub
			Object obj=e.getSource();
			ArticleBean art=new ArticleBean();
			if (obj==hq) {
				jTextField1.setText(Integer.toString(art.getId()));
				jTextField2.setText("");
				jTextField4.setText("");
				jTextField5.setText("");
				jTextField6.setText("");
				jTextField7.setText("");
				jTextField8.setText("");
				jTextField10.setText("");
				jTextField11.setText("");
				addInfo.setEnabled(true);
				deleteInfo.setEnabled(false);
				modifyInfo.setEnabled(false);
			}
	
			else if(obj==clearInfo) {
				jTextField1.setText("");
				jTextField2.setText("");
				jTextField4.setText("");
				jTextField5.setText("");
				jTextField6.setText("");
				jTextField7.setText("");
				jTextField8.setText("");
				jTextField10.setText("");
				jTextField11.setText("");
				deleteInfo.setEnabled(false);
				modifyInfo.setEnabled(false);
			}
			else if (obj==deleteInfo) {
				ArticleBean articleBean=new ArticleBean();
				articleBean.delete(jTextField1.getText());
				Node11Panel node13Panel=new Node11Panel();
				KyMain.splitPane.setRightComponent(node13Panel);
			} 
			else if (obj==addInfo) {
				
				
				art.add(jTextField2.getText(),teacher, jTextField4.getText(), jTextField5.getText(), jTextField6.getText(), jTextField7.getText(), jTextField8.getText(),DeptID,jTextField10.getText(), jTextField11.getText());
				
				Node11Panel node13Panel=new Node11Panel();
				KyMain.splitPane.setRightComponent(node13Panel);
			}
			else if (obj==modifyInfo) {
				art.modify(jTextField1.getText(), jTextField2.getText(), teacher, jTextField4.getText(), jTextField5.getText(), jTextField6.getText(), jTextField7.getText(), jTextField8.getText(), DeptID, jTextField10.getText(), jTextField11.getText());
				Node11Panel node13Panel=new Node11Panel();
				KyMain.splitPane.setRightComponent(node13Panel);
			}
			
			
			
			
			
			
				//重新生成界面 目的是删除记录后 显示删除后的剩余记录
				
				jTable.revalidate();//重新布局
	}
	
		@Override
		public void valueChanged(ListSelectionEvent e) {
			// TODO Auto-generated method stub
			//获取表选中的行的索引号
			int[] selecteRow=jTable.getSelectedRows();
			int[] selecteCol=jTable.getSelectedColumns();
			//定义文本框的现实内容
			//既在上面显示人员表中选中一条记录 下面上颚文本框中分别年是该记录的
			for (int i = 0; i &amp;lt; selecteRow.length; i++) {
				for (int j = 0; j &amp;lt; selecteCol.length; j++) {
					jTextField1.setText(colValue[selecteRow[i]][0]);
					jTextField2.setText(colValue[selecteRow[i]][1]);
					jTextField4.setText(colValue[selecteRow[i]][3]);
					jTextField5.setText(colValue[selecteRow[i]][4]);
					jTextField6.setText(colValue[selecteRow[i]][5]);
					jTextField7.setText(colValue[selecteRow[i]][6]);
					jTextField8.setText(colValue[selecteRow[i]][7]);
					jTextField10.setText(colValue[selecteRow[i]][9]);
					jTextField11.setText(colValue[selecteRow[i]][10]);
				}
			}
			deleteInfo.setEnabled(true);
			modifyInfo.setEnabled(true);
			hq.setEnabled(true);
			
		}
		public void itemStateChanged(ItemEvent e) {
			// TODO Auto-generated method stub
			//ItemEvent--项目事件，例如下拉列表框中项被选定或取消选定的事件 
			//e.getStateChange()--表示选定或取消选定 
			//ItemEvent.SELECTED--表示选定 
			//ItemEvent.DESELECTED--表示取消选定 
			//如果在下拉列表框中选中一个部门 
			//TeacherBean teacherBean=new TeacherBean();
			if (e.getStateChange()==ItemEvent.SELECTED)
			{
				//获取选中项目值，得到的是一个“1-办公室-秘书室”这样的字符串 
				//字符串构成：部门编号-一级部门-二级部门 
				System.out.println("123");
				String temStr=""+e.getItem();
				//返回指定子字符串"-"在此字符串中第一次出现处的索引 
				int i=temStr.indexOf("-");
				 //取部门id子字符串，目的是取前面的部门编号 
				teacher=temStr.substring(0,i);
			}
		}
	
	}

&lt;/pre></description></item><item><title>构建联合查询语句 用于查询三联表中的数据</title><link>https://pangyd.com/post/58/</link><pubDate>Mon, 14 Aug 2017 22:16:11 +0800</pubDate><guid>https://pangyd.com/post/58/</guid><description>&lt;pre lay-lang="Java" class="layui-code" skin="notepad">sql="select *,teacher.teacherID as teacherName, "
						+ "department.depID as depName "
						+ "from teacher,article,department "
						+ "where teacher.teacherID=article.teacherID and department.depID=article.depID "
			
						+ "order by articleID";&lt;/pre></description></item><item><title>executeQueryUnknown column 'admin' in 'where clause' 解决办法</title><link>https://pangyd.com/post/57-executequeryunknown-column-admin-in-where-clause/</link><pubDate>Mon, 14 Aug 2017 15:32:00 +0800</pubDate><guid>https://pangyd.com/post/57-executequeryunknown-column-admin-in-where-clause/</guid><description>&lt;p>这个错误困扰了我两天啊 &amp;nbsp;因为这个错误所以做登陆界面的时候不是用的数据库 所以也不能做注册 修改 &amp;nbsp;&lt;/p>&lt;p>其实原因很简单 &amp;nbsp;而我得找了好几个小时都没有解决 &amp;nbsp;在测试的时候发现传递数字的时候可以返回记录到的字符串&lt;/p>&lt;p>&amp;nbsp;而传递单词却无法返回 &amp;nbsp;就提示报错 &amp;nbsp;我觉着是数据库字符类型设计错了还是怎么得了 百思不得解&lt;/p>&lt;p>接下来说明解决方法：&lt;/p>&lt;p>“select * from user where userName"=admin;&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>select * from user where userName=123&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>其实是因为执行sql查询语句的时候userName的值是数字所以不用加单引号 &amp;nbsp;而admin是英文所以要加上单引号&amp;nbsp;&lt;/p>&lt;p>正确的应该是这样&lt;/p>&lt;p>sql="select * from user where userName='"+field2+"'";&lt;/p>&lt;p>在&lt;span>查询的字符串左右加上英文单冒号 ' '即可&lt;/span>&lt;/p></description></item><item><title>在有main函数的前提下 eclipse找不到主类 解决办法</title><link>https://pangyd.com/post/56-main-eclipse/</link><pubDate>Sun, 13 Aug 2017 21:49:23 +0800</pubDate><guid>https://pangyd.com/post/56-main-eclipse/</guid><description>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>&lt;b>有时候在测试类的时候&lt;a target="_self" href="https://github.com/As-before">eclipse&lt;/a>会莫名奇妙的提示找不到主类 &amp;nbsp; 接下来分别有几种解决办法&lt;/b>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;b>&lt;br>&lt;/b>&lt;/span>&lt;/p>&lt;p>&lt;b>1.&lt;/b>在项目上右击&amp;gt; Builder Path -&amp;gt; Configure Build Path -&amp;gt; 选择Source面板 再点Add Folder, 把源代码所在的包路径的上层目录加进来，而且如果你是把两个类写在一个文件里的话,你在右键选择Run As Java Appication 的时候,要把光标至于包括main方法的类上&lt;/p>&lt;p>2复制粘贴带main函数的类 创建一个新的类把代码复制进去 即可ok&lt;/p>&lt;p>3 直接重建Java项目&lt;/p>&lt;p>如果还是不行 在命令管理器上测试java是否正常运行 &amp;nbsp;如果没有看一下环境变量是否错误 或者重新安装&lt;/p></description></item><item><title>login登陆界面设计</title><link>https://pangyd.com/post/55-login/</link><pubDate>Sun, 13 Aug 2017 12:51:02 +0800</pubDate><guid>https://pangyd.com/post/55-login/</guid><description>&lt;pre lay-lang="Java" class="layui-code" skin="notepad">package com.jnzyjsxy.test;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class login extends Frame implements ActionListener {
TextField txtName;
TextField txtPassword;
Label lblTitle,lblName,lblPassword;
Button btnSubmit;
Button btnReset;

JButton clearInfo=new JButton();
static //创建网格包布局对象
GridBagLayout girdBag=new GridBagLayout();
//创建网格包约束类变量
GridBagConstraints girdBagCon;
public login(){
super("登陆界面");
//lblTitle=new Label("请输入您的用户信息:");
lblName=new Label("用户名:");
txtName=new TextField(15);
txtName.setFont(new Font("Dialog", 0, 15));
lblPassword=new Label("密码:");
txtPassword=new TextField(15);
txtPassword.setFont(new Font("Dialog", 0, 15));
txtPassword.setEchoChar('*');
btnSubmit=new Button("提交");
btnReset=new Button("重置");
//lblName.setText("用户名");

lblName.setFont(new Font("Dialog", 0, 16));
girdBagCon=new GridBagConstraints();
girdBagCon.gridx=0;
girdBagCon.gridy=1;
//外部填充 4个参数 top,left,bottom,right
//既外部间距
girdBagCon.insets=new Insets(0, 10, 10, 1);
girdBag.setConstraints(lblName, girdBagCon);
this.add(lblName);

girdBagCon=new GridBagConstraints();
girdBagCon.gridx=1;
girdBagCon.gridy=1;
girdBagCon.insets=new Insets(0, 1, 10, 15);
girdBag.setConstraints(txtName, girdBagCon);
this.add(txtName);

//lblPassword.setText("");
lblPassword.setFont(new Font("Dialog", 0, 16));
girdBagCon=new GridBagConstraints();
girdBagCon.gridx=0;
girdBagCon.gridy=2;
//外部填充 4个参数 top,left,bottom,right
//既外部间距
girdBagCon.insets=new Insets(0, 15, 10, 1);
girdBag.setConstraints(lblPassword, girdBagCon);
this.add(lblPassword);

girdBagCon=new GridBagConstraints();
girdBagCon.gridx=1;
girdBagCon.gridy=2;
girdBagCon.insets=new Insets(0, 1, 10, 15);
girdBag.setConstraints(txtPassword, girdBagCon);
this.add(txtPassword);

//addInfo.setText("增加");
btnSubmit.setFont(new Font("Dialog", 0, 16));
girdBagCon=new GridBagConstraints();
girdBagCon.gridx=0;
girdBagCon.gridy=3;
girdBagCon.gridwidth=2;
girdBagCon.gridheight=1;
//外部填充 4个参数 top,left,bottom,right
//既外部间距
girdBagCon.insets=new Insets(10, 10, 10, 90);
girdBag.setConstraints(btnSubmit, girdBagCon);
this.add(btnSubmit);

//clearInfo.setText("清空");
btnReset.setFont(new Font("Dialog", 0, 16));
girdBagCon=new GridBagConstraints();
girdBagCon.gridx=1;
girdBagCon.gridy=3;
girdBagCon.gridwidth=2;
girdBagCon.gridheight=1;
//外部填充 4个参数 top,left,bottom,right
//既外部间距
girdBagCon.insets=new Insets(10, 10, 10, -30);
girdBag.setConstraints(btnReset, girdBagCon);
this.add(btnReset);

this.btnSubmit.addActionListener(this);
this.btnReset.addActionListener(this);
addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
public void actionPerformed(ActionEvent e){
String s=e.getActionCommand();
if(s.equals("重置")){
clear();
}else if(s.equals("提交")){
submit();
}else if(e.getSource()==txtName){
txtPassword.requestFocus();
}else if(e.getSource()==txtPassword){
submit();
}
}
public void clear(){
txtName.setText("");
txtPassword.setText("");
txtName.requestFocus();
}
public void submit(){
String n=txtName.getText();
String paw=txtPassword.getText();
if(n.equals("admin") &amp;amp;&amp;amp; paw.equals("123")){
JOptionPane.showMessageDialog(this,"合法用户，欢迎进入本系统");
	HrP hrP=new HrP();
}else{
	
		JOptionPane.showMessageDialog(this, "非法用户，禁止进入本系统");
		System.exit(0);
		

}
}
public static void main(String[] args) {
	try {
		//UIManager--界面管理类
		//外观设置成所使用的操作平台的外观
		//即程序在哪个平台运行，显示的窗口，对话框将是哪个平台的外观
		UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		login ttf=new login();
		ttf.setSize(300,200);
		//获取屏幕大小
				Dimension screenSize=Toolkit.getDefaultToolkit().getScreenSize();
				//获取当前项目的窗体大小
				Dimension frameSize=ttf.getSize();
				//如果项目窗体高&amp;gt;屏幕高，用屏幕高设置项目窗体高
				if (frameSize.height&amp;gt;screenSize.height) {
					frameSize.height=screenSize.height;
				}
				if (frameSize.width&amp;gt;screenSize.width) {
					frameSize.width=screenSize.width;
				}
		ttf.setLocation((screenSize.width-frameSize.width)/2,
				(screenSize.height-frameSize.height)/2);;
		ttf.setLayout(girdBag);
		 ttf.setResizable(false);
		ttf.setVisible(true);
		
	} catch (Exception e) {
		// TODO: handle exception
		e.printStackTrace();
	}
	//创建主类对象测试项目
	new login();

}

}&lt;/pre></description></item><item><title>The project: Java which is referenced by the classpath, does not exist. 错误处理办法</title><link>https://pangyd.com/post/53-the-project-java-which-is-referenced-by-the-clas/</link><pubDate>Sat, 12 Aug 2017 21:18:29 +0800</pubDate><guid>https://pangyd.com/post/53-the-project-java-which-is-referenced-by-the-clas/</guid><description>&lt;pre id="best-content-1737161415" accuse="aContent" class="best-text mb-10">在property-java build path-&amp;gt; project s tab把依赖去掉&lt;/pre></description></item><item><title>转载自【 Java编程精选】深入理解 Java final 变量的内存模型</title><link>https://pangyd.com/post/52-java-java-final/</link><pubDate>Fri, 11 Aug 2017 22:11:15 +0800</pubDate><guid>https://pangyd.com/post/52-java-java-final/</guid><description>&lt;p>对于 final 域，编译器和处理器要遵守两个重排序规则：&lt;/p>&lt;ul class="list-paddingleft-2">&lt;li>&lt;p>在构造函数内对一个 final 域的写，与随后把这个构造对象的引用赋值给一个变量，这两个操作之间不能重排序&lt;/p>&lt;/li>&lt;li>&lt;p>初次读一个包含 final 域的对象的引用，与随后初次读这个 final 域，这两个操作之间不能重排序&lt;/p>&lt;/li>&lt;/ul>&lt;p>举个例子：&lt;/p>&lt;table cellpadding="0" cellspacing="0" width="620" height="NaN" class="layui-table">&lt;tbody>&lt;tr>&lt;td class="" width="NaN" height="NaN">&lt;div class="" style="text-align: right">1&lt;/div>&lt;div class="" style="text-align: right">2&lt;/div>&lt;div class="" style="text-align: right">3&lt;/div>&lt;div class="" style="text-align: right">4&lt;/div>&lt;div class="" style="text-align: right">5&lt;/div>&lt;div class="" style="text-align: right">6&lt;/div>&lt;div class="" style="text-align: right">7&lt;/div>&lt;div class="" style="text-align: right">8&lt;/div>&lt;div class="" style="text-align: right">9&lt;/div>&lt;div class="" style="text-align: right">10&lt;/div>&lt;div class="" style="text-align: right">11&lt;/div>&lt;div class="" style="text-align: right">12&lt;/div>&lt;div class="" style="text-align: right">13&lt;/div>&lt;div class="" style="text-align: right">14&lt;/div>&lt;div class="" style="text-align: right">15&lt;/div>&lt;div class="" style="text-align: right">16&lt;/div>&lt;div class="" style="text-align: right">17&lt;/div>&lt;div class="" style="text-align: right">18&lt;/div>&lt;div class="" style="text-align: right">19&lt;/div>&lt;div class="" style="text-align: right">20&lt;/div>&lt;/td>&lt;td class="" width="585" height="NaN">&lt;div class="">&lt;code class="">public&lt;/code> &lt;code class="">class&lt;/code> &lt;code class="">FinalExample {&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">int&lt;/code> &lt;code class="">i;&lt;/code>&lt;code class="">// 普通变量&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">final&lt;/code> &lt;code class="">int&lt;/code> &lt;code class="">j;&lt;/code>&lt;code class="">// final 变量&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">static&lt;/code> &lt;code class="">FinalExample obj;&lt;/code>&lt;/div>&lt;div class="">&amp;nbsp;&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">public&lt;/code> &lt;code class="">FinalExample() {&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">i = &lt;/code>&lt;code class="">1&lt;/code>&lt;code class="">;&lt;/code>&lt;code class="">// 写普通域&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">j = &lt;/code>&lt;code class="">2&lt;/code>&lt;code class="">;&lt;/code>&lt;code class="">// 写 final 域&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">}&lt;/code>&lt;/div>&lt;div class="">&amp;nbsp;&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">public&lt;/code> &lt;code class="">static&lt;/code> &lt;code class="">void&lt;/code> &lt;code class="">writer() {&lt;/code>&lt;code class="">// 写线程 A 执行&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">obj = &lt;/code>&lt;code class="">new&lt;/code> &lt;code class="">FinalExample();&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">}&lt;/code>&lt;/div>&lt;div class="">&amp;nbsp;&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">public&lt;/code> &lt;code class="">static&lt;/code> &lt;code class="">void&lt;/code> &lt;code class="">reader() {&lt;/code>&lt;code class="">// 读线程 B 执行&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">FinalExample object = obj;&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">int&lt;/code> &lt;code class="">a = object.i;&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">int&lt;/code> &lt;code class="">b = object.j;&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">}&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">}&lt;/code>&lt;/div>&lt;/td>&lt;/tr>&lt;/tbody>&lt;/table>&lt;p>这里假设一个线程 A 执行 writer ()方法,随后另一个线程 B 执行 reader ()方法。&lt;/p></description></item><item><title>转载自【 Java编程精选】SpringBoot(二) ：web综合开发</title><link>https://pangyd.com/post/51-javaspringboot-web/</link><pubDate>Fri, 11 Aug 2017 21:09:16 +0800</pubDate><guid>https://pangyd.com/post/51-javaspringboot-web/</guid><description>&lt;p>上篇文章介绍了Spring boot初级教程：spring boot(一)：入门篇，方便大家快速入门、了解实践Spring boot特性；本篇文章接着上篇内容继续为大家介绍spring boot的其它特性（有些未必是spring boot体系桟的功能，但是是spring特别推荐的一些开源技术本文也会介绍），对了这里只是一个大概的介绍，特别详细的使用我们会在其它的文章中来展开说明。&lt;/p>&lt;p>&lt;img data-s="300,640" data-type="jpeg" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" class="" data-ratio="0.5625" data-w="1280" src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-fail="0">&lt;/p>&lt;h2>web开发&lt;/h2>&lt;p>spring boot web开发非常的简单，其中包括常用的json输出、filters、property、log等&lt;/p>&lt;h3>json 接口开发&lt;/h3>&lt;p>在以前的spring 开发的时候需要我们提供json接口的时候需要做那些配置呢&lt;/p>&lt;ul class="list-paddingleft-2">&lt;li>&lt;p>添加 jackjson 等相关jar包&lt;/p>&lt;/li>&lt;li>&lt;p>配置spring controller扫描&lt;/p>&lt;/li>&lt;li>&lt;p>对接的方法添加@ResponseBody&lt;/p>&lt;/li>&lt;/ul>&lt;p>就这样我们会经常由于配置错误，导致406错误等等，spring boot如何做呢，只需要类添加 @RestController 即可，默认类中的方法都会以json的格式返回&lt;/p>&lt;table cellpadding="0" cellspacing="0" width="620" height="NaN" class="layui-table">&lt;tbody>&lt;tr>&lt;td class="" width="NaN" height="NaN">&lt;div class="" style="text-align: right">1&lt;/div>&lt;div class="" style="text-align: right">2&lt;/div>&lt;div class="" style="text-align: right">3&lt;/div>&lt;div class="" style="text-align: right">4&lt;/div>&lt;div class="" style="text-align: right">5&lt;/div>&lt;div class="" style="text-align: right">6&lt;/div>&lt;div class="" style="text-align: right">7&lt;/div>&lt;div class="" style="text-align: right">8&lt;/div>&lt;div class="" style="text-align: right">9&lt;/div>&lt;div class="" style="text-align: right">10&lt;/div>&lt;/td>&lt;td class="" width="585" height="NaN">&lt;div class="">&lt;code class="">@RestController&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">public&lt;/code> &lt;code class="">class&lt;/code> &lt;code class="">HelloWorldController {&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">@RequestMapping&lt;/code>&lt;code class="">(&lt;/code>&lt;code class="">"/getUser"&lt;/code>&lt;code class="">)&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">public&lt;/code> &lt;code class="">User getUser() {&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">User user=&lt;/code>&lt;code class="">new&lt;/code> &lt;code class="">User();&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">user.setUserName(&lt;/code>&lt;code class="">"小明"&lt;/code>&lt;code class="">);&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">user.setPassWord(&lt;/code>&lt;code class="">"xxxx"&lt;/code>&lt;code class="">);&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">return&lt;/code> &lt;code class="">user;&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">}&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">}&lt;/code>&lt;/div>&lt;/td>&lt;/tr>&lt;/tbody>&lt;/table>&lt;p>如果我们需要使用页面开发只要使用 @Controller ，下面会结合模板来说明&lt;/p>&lt;h3>自定义Filter&lt;/h3>&lt;p>我们常常在项目中会使用filters用于录调用日志、排除有XSS威胁的字符、执行权限验证等等。Spring Boot自动添加了OrderedCharacterEncodingFilter和HiddenHttpMethodFilter，并且我们可以自定义Filter。&lt;/p>&lt;p>两个步骤：&lt;/p>&lt;ol class="list-paddingleft-2">&lt;li>&lt;p>实现Filter接口，实现Filter方法&lt;/p>&lt;/li>&lt;li>&lt;p>添加@Configurationz 注解，将自定义Filter加入过滤链&lt;/p>&lt;/li>&lt;/ol>&lt;p>好吧，直接上代码&lt;/p>&lt;table cellpadding="0" cellspacing="0" width="794" height="NaN" class="layui-table">&lt;tbody>&lt;tr>&lt;td class="" width="NaN" height="NaN">&lt;div class="" style="text-align: right">1&lt;/div>&lt;div class="" style="text-align: right">2&lt;/div>&lt;div class="" style="text-align: right">3&lt;/div>&lt;div class="" style="text-align: right">4&lt;/div>&lt;div class="" style="text-align: right">5&lt;/div>&lt;div class="" style="text-align: right">6&lt;/div>&lt;div class="" style="text-align: right">7&lt;/div>&lt;div class="" style="text-align: right">8&lt;/div>&lt;div class="" style="text-align: right">9&lt;/div>&lt;div class="" style="text-align: right">10&lt;/div>&lt;div class="" style="text-align: right">11&lt;/div>&lt;div class="" style="text-align: right">12&lt;/div>&lt;div class="" style="text-align: right">13&lt;/div>&lt;div class="" style="text-align: right">14&lt;/div>&lt;div class="" style="text-align: right">15&lt;/div>&lt;div class="" style="text-align: right">16&lt;/div>&lt;div class="" style="text-align: right">17&lt;/div>&lt;div class="" style="text-align: right">18&lt;/div>&lt;div class="" style="text-align: right">19&lt;/div>&lt;div class="" style="text-align: right">20&lt;/div>&lt;div class="" style="text-align: right">21&lt;/div>&lt;div class="" style="text-align: right">22&lt;/div>&lt;div class="" style="text-align: right">23&lt;/div>&lt;div class="" style="text-align: right">24&lt;/div>&lt;div class="" style="text-align: right">25&lt;/div>&lt;div class="" style="text-align: right">26&lt;/div>&lt;div class="" style="text-align: right">27&lt;/div>&lt;div class="" style="text-align: right">28&lt;/div>&lt;div class="" style="text-align: right">29&lt;/div>&lt;div class="" style="text-align: right">30&lt;/div>&lt;div class="" style="text-align: right">31&lt;/div>&lt;div class="" style="text-align: right">32&lt;/div>&lt;div class="" style="text-align: right">33&lt;/div>&lt;div class="" style="text-align: right">34&lt;/div>&lt;div class="" style="text-align: right">35&lt;/div>&lt;div class="" style="text-align: right">36&lt;/div>&lt;div class="" style="text-align: right">37&lt;/div>&lt;div class="" style="text-align: right">38&lt;/div>&lt;div class="" style="text-align: right">39&lt;/div>&lt;div class="" style="text-align: right">40&lt;/div>&lt;/td>&lt;td class="" width="759" height="NaN">&lt;div class="">&lt;code class="">@Configuration&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">public&lt;/code> &lt;code class="">class&lt;/code> &lt;code class="">WebConfiguration {&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">@Bean&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">public&lt;/code> &lt;code class="">RemoteIpFilter remoteIpFilter() {&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">return&lt;/code> &lt;code class="">new&lt;/code> &lt;code class="">RemoteIpFilter();&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">}&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&amp;nbsp;&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">@Bean&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">public&lt;/code> &lt;code class="">FilterRegistrationBean testFilterRegistration() {&lt;/code>&lt;/div>&lt;div class="">&amp;nbsp;&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">FilterRegistrationBean registration = &lt;/code>&lt;code class="">new&lt;/code> &lt;code class="">FilterRegistrationBean();&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">registration.setFilter(&lt;/code>&lt;code class="">new&lt;/code> &lt;code class="">MyFilter());&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">registration.addUrlPatterns(&lt;/code>&lt;code class="">"/*"&lt;/code>&lt;code class="">);&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">registration.addInitParameter(&lt;/code>&lt;code class="">"paramName"&lt;/code>&lt;code class="">, &lt;/code>&lt;code class="">"paramValue"&lt;/code>&lt;code class="">);&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">registration.setName(&lt;/code>&lt;code class="">"MyFilter"&lt;/code>&lt;code class="">);&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">registration.setOrder(&lt;/code>&lt;code class="">1&lt;/code>&lt;code class="">);&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">return&lt;/code> &lt;code class="">registration;&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">}&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&amp;nbsp;&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">public&lt;/code> &lt;code class="">class&lt;/code> &lt;code class="">MyFilter &lt;/code>&lt;code class="">implements&lt;/code> &lt;code class="">Filter {&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">@Override&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">public&lt;/code> &lt;code class="">void&lt;/code> &lt;code class="">destroy() {&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">// TODO Auto-generated method stub&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">}&lt;/code>&lt;/div>&lt;div class="">&amp;nbsp;&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">@Override&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">public&lt;/code> &lt;code class="">void&lt;/code> &lt;code class="">doFilter(ServletRequest srequest, ServletResponse sresponse, FilterChain filterChain)&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">throws&lt;/code> &lt;code class="">IOException, ServletException {&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">// TODO Auto-generated method stub&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">HttpServletRequest request = (HttpServletRequest) srequest;&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">System.out.println(&lt;/code>&lt;code class="">"this is MyFilter,url :"&lt;/code>&lt;code class="">+request.getRequestURI());&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">filterChain.doFilter(srequest, sresponse);&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">}&lt;/code>&lt;/div>&lt;div class="">&amp;nbsp;&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">@Override&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">public&lt;/code> &lt;code class="">void&lt;/code> &lt;code class="">init(FilterConfig arg0) &lt;/code>&lt;code class="">throws&lt;/code> &lt;code class="">ServletException {&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">// TODO Auto-generated method stub&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">}&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">}&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">}&lt;/code>&lt;/div>&lt;/td>&lt;/tr>&lt;/tbody>&lt;/table>&lt;h3>自定义Property&lt;/h3>&lt;p>在web开发的过程中，我经常需要自定义一些配置文件，如何使用呢&lt;/p></description></item><item><title>转载自【 Java编程精选】SpringBoot (一) ：入门篇</title><link>https://pangyd.com/post/50-javaspringboot/</link><pubDate>Fri, 11 Aug 2017 20:08:20 +0800</pubDate><guid>https://pangyd.com/post/50-javaspringboot/</guid><description>&lt;p style="text-align: center">&lt;br>&lt;/p>&lt;p style="text-align: center">Spring Boot是由Pivotal团队提供的全新框架，其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置，从而使开发人员不再需要定义样板化的配置。用我的话来理解，就是spring boot其实不是什么新的框架，它默认配置了很多框架的使用方式，就像maven整合了所有的jar包，spring boot整合了所有的框架（不知道这样比喻是否合适）。&lt;/p>&lt;p style="text-align: center">&lt;img data-s="300,640" data-type="png" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" class="" data-ratio="0.5908372827804107" data-w="633" src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-fail="0">&lt;/p>&lt;p style="text-align: center">使用spring boot有什么好处&lt;br>1）配置web.xml，加载spring和spring mvc&lt;br>2）配置数据库连接、配置spring事务&lt;br>3）配置加载配置文件的读取，开启注解&lt;br>4）配置日志文件&lt;br>…&lt;br>配置完成之后部署tomcat 调试&lt;br>…&lt;br>现在非常流行微服务，如果我这个项目仅仅只是需要发送一个邮件，如果我的项目仅仅是生产一个积分；我都需要这样折腾一遍!&lt;br>但是如果使用spring boot呢？&lt;br>很简单，我仅仅只需要非常少的几个配置就可以迅速方便的搭建起来一套web项目或者是构建一个微服务！&lt;br>快速入门&lt;br>maven构建项目&lt;br>1、访问https://start.spring.io/&lt;br>2、选择构建工具Maven Project、Spring Boot版本1.3.6以及一些工程基本信息，点击“Switch to the full version.”java版本选择1.7，可参考下图所示：&lt;br>3、点击Generate Project下载项目压缩包&lt;br>4、解压后，使用eclipse，Import -&amp;gt; Existing Maven Projects -&amp;gt; Next -&amp;gt;选择解压后的文件夹-&amp;gt; Finsh，OK done!&lt;br>项目结构介绍&lt;br>另外，spingboot建议的目录结果如下：&lt;br>root package结构：com.example.myproject&lt;table cellpadding="0" cellspacing="0" width="620" height="NaN" class="layui-table" style="text-align: center">&lt;tbody>&lt;tr>&lt;td class="" width="NaN" height="NaN">&lt;div class="" style="text-align: right">1&lt;/div>&lt;div class="" style="text-align: right">2&lt;/div>&lt;div class="" style="text-align: right">3&lt;/div>&lt;div class="" style="text-align: right">4&lt;/div>&lt;div class="" style="text-align: right">5&lt;/div>&lt;div class="" style="text-align: right">6&lt;/div>&lt;div class="" style="text-align: right">7&lt;/div>&lt;div class="" style="text-align: right">8&lt;/div>&lt;div class="" style="text-align: right">9&lt;/div>&lt;div class="" style="text-align: right">10&lt;/div>&lt;div class="" style="text-align: right">11&lt;/div>&lt;div class="" style="text-align: right">12&lt;/div>&lt;div class="" style="text-align: right">13&lt;/div>&lt;div class="" style="text-align: right">14&lt;/div>&lt;div class="" style="text-align: right">15&lt;/div>&lt;/td>&lt;td class="" width="585" height="NaN">&lt;div class="">&lt;code class="">com&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">+- example&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">+- myproject&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">+- Application.java&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">|&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">+- domain&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">|&amp;nbsp; +- Customer.java&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">|&amp;nbsp; +- CustomerRepository.java&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">|&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">+- service&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">|&amp;nbsp; +- CustomerService.java&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">|&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">+- controller&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">|&amp;nbsp; +- CustomerController.java&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">|&lt;/code>&lt;/div>&lt;/td>&lt;/tr>&lt;/tbody>&lt;/table>1、Application.java 建议放到根目录下面,主要用于做一些框架配置&lt;br>2、domain目录主要用于实体（Entity）与数据访问层（Repository）&lt;br>3、service 层主要是业务类代码&lt;br>4、controller 负责页面访问控制&lt;br>采用默认配置可以省去很多配置，当然也可以根据自己的喜欢来进行更改&lt;br>最后，启动Application main方法，至此一个java项目搭建好了！&lt;br>引入web模块&lt;table cellpadding="0" cellspacing="0" width="620" height="NaN" class="layui-table" style="text-align: center">&lt;tbody>&lt;tr>&lt;td class="" width="NaN" height="NaN">&lt;div class="" style="text-align: right">1&lt;/div>&lt;div class="" style="text-align: right">2&lt;/div>&lt;div class="" style="text-align: right">3&lt;/div>&lt;div class="" style="text-align: right">4&lt;/div>&lt;/td>&lt;td class="" width="592" height="NaN">&lt;div class="">&lt;code class="">&amp;lt;dependency&amp;gt;&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">&amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">&amp;lt;artifactId&amp;gt;spring-boot-starter-web&amp;lt;/artifactId&amp;gt;&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&lt;/code>&lt;code class="">&amp;lt;/dependency&amp;gt;&lt;/code>&lt;/div>&lt;/td>&lt;/tr>&lt;/tbody>&lt;/table>&lt;table cellpadding="0" cellspacing="0" width="620" height="NaN" class="layui-table" style="text-align: center">&lt;tbody>&lt;tr>&lt;td class="" width="NaN" height="NaN">&lt;div class="" style="text-align: right">1&lt;/div>&lt;div class="" style="text-align: right">2&lt;/div>&lt;div class="" style="text-align: right">3&lt;/div>&lt;div class="" style="text-align: right">4&lt;/div>&lt;div class="" style="text-align: right">5&lt;/div>&lt;div class="" style="text-align: right">6&lt;/div>&lt;div class="" style="text-align: right">7&lt;/div>&lt;/td>&lt;td class="" width="592" height="NaN">&lt;div class="">&lt;code class="">@RestController&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">public&lt;/code> &lt;code class="">class&lt;/code> &lt;code class="">HelloWorldController {&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">@RequestMapping&lt;/code>&lt;code class="">(&lt;/code>&lt;code class="">"/hello"&lt;/code>&lt;code class="">)&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">public&lt;/code> &lt;code class="">String index() {&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">return&lt;/code> &lt;code class="">"Hello World"&lt;/code>&lt;code class="">;&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">}&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">}&lt;/code>&lt;/div>&lt;/td>&lt;/tr>&lt;/tbody>&lt;/table>&lt;table cellpadding="0" cellspacing="0" width="675" height="NaN" class="layui-table" style="text-align: center">&lt;tbody>&lt;tr>&lt;td class="" width="NaN" height="NaN">&lt;div class="" style="text-align: right">1&lt;/div>&lt;div class="" style="text-align: right">2&lt;/div>&lt;div class="" style="text-align: right">3&lt;/div>&lt;div class="" style="text-align: right">4&lt;/div>&lt;div class="" style="text-align: right">5&lt;/div>&lt;div class="" style="text-align: right">6&lt;/div>&lt;div class="" style="text-align: right">7&lt;/div>&lt;div class="" style="text-align: right">8&lt;/div>&lt;div class="" style="text-align: right">9&lt;/div>&lt;div class="" style="text-align: right">10&lt;/div>&lt;div class="" style="text-align: right">11&lt;/div>&lt;div class="" style="text-align: right">12&lt;/div>&lt;div class="" style="text-align: right">13&lt;/div>&lt;div class="" style="text-align: right">14&lt;/div>&lt;div class="" style="text-align: right">15&lt;/div>&lt;div class="" style="text-align: right">16&lt;/div>&lt;div class="" style="text-align: right">17&lt;/div>&lt;/td>&lt;td class="" width="640" height="NaN">&lt;div class="">&lt;code class="">@RunWith&lt;/code>&lt;code class="">(SpringJUnit4ClassRunner.&lt;/code>&lt;code class="">class&lt;/code>&lt;code class="">)&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">@SpringApplicationConfiguration&lt;/code>&lt;code class="">(classes = MockServletContext.&lt;/code>&lt;code class="">class&lt;/code>&lt;code class="">)&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">@WebAppConfiguration&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">public&lt;/code> &lt;code class="">class&lt;/code> &lt;code class="">HelloWorldControlerTests {&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">private&lt;/code> &lt;code class="">MockMvc mvc;&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">@Before&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">public&lt;/code> &lt;code class="">void&lt;/code> &lt;code class="">setUp() &lt;/code>&lt;code class="">throws&lt;/code> &lt;code class="">Exception {&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">mvc = MockMvcBuilders.standaloneSetup(&lt;/code>&lt;code class="">new&lt;/code> &lt;code class="">HelloWorldController()).build();&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">}&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">@Test&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">public&lt;/code> &lt;code class="">void&lt;/code> &lt;code class="">getHello() &lt;/code>&lt;code class="">throws&lt;/code> &lt;code class="">Exception {&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">mvc.perform(MockMvcRequestBuilders.get(&lt;/code>&lt;code class="">"/hello"&lt;/code>&lt;code class="">).accept(MediaType.APPLICATION_JSON))&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">.andExpect(MockMvcResultMatchers.status().isOk())&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">.andDo(MockMvcResultHandlers.print())&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">.andReturn();&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">}&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">}&lt;/code>&lt;/div>&lt;/td>&lt;/tr>&lt;/tbody>&lt;/table>开发环境的调试&lt;table cellpadding="0" cellspacing="0" width="620" height="NaN" class="layui-table" style="text-align: center">&lt;tbody>&lt;tr>&lt;td class="" width="NaN" height="NaN">&lt;div class="" style="text-align: right">1&lt;/div>&lt;div class="" style="text-align: right">2&lt;/div>&lt;div class="" style="text-align: right">3&lt;/div>&lt;div class="" style="text-align: right">4&lt;/div>&lt;div class="" style="text-align: right">5&lt;/div>&lt;div class="" style="text-align: right">6&lt;/div>&lt;div class="" style="text-align: right">7&lt;/div>&lt;div class="" style="text-align: right">8&lt;/div>&lt;div class="" style="text-align: right">9&lt;/div>&lt;div class="" style="text-align: right">10&lt;/div>&lt;div class="" style="text-align: right">11&lt;/div>&lt;div class="" style="text-align: right">12&lt;/div>&lt;div class="" style="text-align: right">13&lt;/div>&lt;div class="" style="text-align: right">14&lt;/div>&lt;div class="" style="text-align: right">15&lt;/div>&lt;div class="" style="text-align: right">16&lt;/div>&lt;div class="" style="text-align: right">17&lt;/div>&lt;div class="" style="text-align: right">18&lt;/div>&lt;div class="" style="text-align: right">19&lt;/div>&lt;/td>&lt;td class="" width="585" height="NaN">&lt;div class="">&lt;code class="">&amp;lt;dependencies&amp;gt;&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">&amp;lt;dependency&amp;gt;&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">&amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">&amp;lt;artifactId&amp;gt;spring-boot-devtools&amp;lt;/artifactId&amp;gt;&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">&amp;lt;optional&amp;gt;&lt;/code>&lt;code class="">true&lt;/code>&lt;code class="">&amp;lt;/optional&amp;gt;&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">&amp;lt;/dependency&amp;gt;&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;lt;/dependencies&amp;gt;&lt;/code>&lt;/div>&lt;div class="">&amp;nbsp;&lt;/div>&lt;div class="">&lt;code class="">&amp;lt;build&amp;gt;&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">&amp;lt;plugins&amp;gt;&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">&amp;lt;plugin&amp;gt;&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">&amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">&amp;lt;artifactId&amp;gt;spring-boot-maven-plugin&amp;lt;/artifactId&amp;gt;&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">&amp;lt;configuration&amp;gt;&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">&amp;lt;fork&amp;gt;&lt;/code>&lt;code class="">true&lt;/code>&lt;code class="">&amp;lt;/fork&amp;gt;&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">&amp;lt;/configuration&amp;gt;&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code>&lt;code class="">&amp;lt;/plugin&amp;gt;&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;lt;/plugins&amp;gt;&lt;/code>&lt;/div>&lt;div class="">&lt;code class="">&amp;lt;/build&amp;gt;&lt;/code>&lt;/div>&lt;/td>&lt;/tr>&lt;/tbody>&lt;/table>总结&lt;/p></description></item><item><title>转载自【Java编程精选】Java Web架构知识整理——记一次阿里面试经历</title><link>https://pangyd.com/post/49-javajava-web/</link><pubDate>Thu, 10 Aug 2017 20:47:53 +0800</pubDate><guid>https://pangyd.com/post/49-javajava-web/</guid><description>&lt;p>&lt;br>&lt;/p>&lt;p>“你学习一门技术的最佳时机是三年前，其次是现在。”这话从来很灵验。经过这次面试，觉得需要整理下Java Web相关的资料，以便自己提高或者更快适应可能面临的新的工作。&lt;/p>&lt;p>首先谈谈Java Web需要掌握哪些东西。这里是一些知识点的搜集，暂不做详细说明，欢迎各位博友补充指正。&lt;/p>&lt;h2>&lt;strong>1.底层&lt;/strong>&lt;/h2>&lt;p>&lt;strong>&lt;br>&lt;/strong>&lt;/p>&lt;ul class="list-paddingleft-2">&lt;li>&lt;p>&lt;span>Java语言相关的就不说了，首先是JVM的结构和工作原理。比较重要的是Java内存模型，各种GC算法，Classloader的加载原理等。个人对底层的一些东西还算比较了解，所以不过多纠结，实际上程序编译链接过程以及二进制文件的处理还是很值得研究的。&lt;/span>&lt;/p>&lt;/li>&lt;li>&lt;p>&lt;span>JVM监控及调优。作为一个开发人员并不一定需要非常熟悉JVM调优的方法，但如果具备JVM监控及调优的能力，将让你对程序运行状况了如指掌，对于问题定位也会敏感得多。&lt;/span>&lt;/p>&lt;/li>&lt;li>&lt;p>&lt;span>Java多线程。对于线程安全的理解，以及如何在自己的程序中避免多线程造成的不一致问题等。&lt;/span>&lt;/p>&lt;/li>&lt;li>&lt;p>&lt;span>I/O。Java中常常提到的是BIO/NIO，即阻塞型I/O与非阻塞型I/O，其实并不难理解，结合Linux中的同步I/O和异步I/O的实现原理，基本都是相通的，每种I/O方式解决的问题，又存在什么问题，为什么使用epoll。&lt;/span>&lt;/p>&lt;/li>&lt;/ul>&lt;h2>&lt;strong>&lt;br>&lt;/strong>&lt;/h2>&lt;h2>&lt;strong>2.Servlet&lt;/strong>&lt;/h2>&lt;p>&lt;br>&lt;/p>&lt;p>Servlet是运行于服务端的java程序，一般实现自己的Java服务端应用都从HttpServlet类继承，然后实现自己的init | doGet | doPost | service方法。Servlet的生命周期从其加载开始，首先执行一次初始化，调用init方法，之后便可运行自身的服务，当生命周期结束时，调用destroy方法回收资源，结束服务。&lt;/p>&lt;p>仅了解原理当然是不够的，还要实战能力，在IDE中写写简单的代码谁都会，然而真正让一个程序能够运行起来也还需要点其他的东西，这里我指的是Servlet的容器。servlet的容器有很多，常用的以Tomcat为例，安装好Tomcat后，在开发时必须包含进Tomcat的lib。IDE确实惯坏了好多人，目录如何组织，程序如何编译、如何部署这些问题都被IDE屏蔽掉了，如果要对整体有比较透彻的了解，建议一切从命令行动手。&lt;/p>&lt;p>具体可参考：《Servlet与JSP核心编程》。&lt;/p>&lt;h2>&lt;strong>3.框架&lt;/strong>&lt;/h2>&lt;p>&lt;br>&lt;/p>&lt;p>Java Web开发的用到的框架之多简直令人发指，而且因为版本的更新换代导致的问题也是层出不穷。然而这也是Web技术不断演化的结果，要么选择接受，要么引领节奏。&lt;/p>&lt;h3>Spring&lt;/h3>&lt;p>Spring是一个强大而又“轻量级”的Java开发框架，之所以打引号是因为感觉并不是那么轻量。Spring的主要目的在于简化Java应用开发，以配置方式代替硬编码方式的编程，模块解耦，其架构如下图所示。包括了数据访问、远程通信、AOP、核心容器等部分。&lt;/p>&lt;p>&lt;img class="" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" width="740" height="540" data-ratio="0.7297297297297297" data-w="740" data-type="png" src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-fail="0">&lt;/p>&lt;p>&lt;strong>&amp;nbsp;Figure 1 Spring体系架构&lt;/strong>&lt;/p>&lt;p>Spring的核心主要有三点：&lt;/p>&lt;ul class="list-paddingleft-2">&lt;li>&lt;p>&lt;em>&lt;strong>IoC&lt;/strong>&lt;/em>：反转控制。&lt;/p>&lt;/li>&lt;/ul>&lt;p>反转控制就是指将控制权由类内部抽离到容器，由容器类的实例化及动作进行配置管理。&lt;/p>&lt;ul class="list-paddingleft-2">&lt;li>&lt;p>&lt;strong>&lt;em>Dependency-injection&lt;/em>&lt;/strong>：依赖注入&lt;/p>&lt;/li>&lt;/ul>&lt;p>对象的依赖关系由负责协调系统中各个对象的第三方组件在创建对象时设定。对象不自行创建或管理它们的依赖关系，依赖关系被自动注入到需要它们的对象中。通过参数和配置能够体会出“注入”这个词在这里有多形象。依赖注入的最大好处就是松耦合。不需要再类内部去和特定的类进行绑定，而是将一些依赖关系以参数的形式注入到类内部。&lt;/p>&lt;ul class="list-paddingleft-2">&lt;li>&lt;p>&lt;em>&lt;strong>Aspect Oriented Programming&lt;/strong>&lt;/em>：面向切向编程&lt;/p>&lt;/li>&lt;/ul>&lt;p>在软件开发中，分布于应用中多处的功能被称为横切关注点。这些横切关注点往往和业务逻辑是相分离的，将这些横切关注点与业务逻辑相分离正式AOP要解决的。AOP编程能够让遍布在应用各处的功能分离出来形成可重用的组件。是高内聚低耦合的又一个体现，将通用实现模块与核心业务模块相分离。&lt;/p>&lt;p>具体参考：《Spring In Action》&lt;/p>&lt;h2>&lt;strong>Hibernate&lt;/strong>&lt;/h2>&lt;p>&lt;br>&lt;/p>&lt;p>数据持久化框架其实也有很多，需要掌握的不仅是Hibernate，只是因为Hibernate在以前的企业级应用中用的比较多而已，另外MyBatis也占有相当重要的份额。Hibernate是一个全自动的持久化框架，并不是那么方便，所以很多开发者更倾向于使用MyBatis，淘宝就是这样。&lt;/p>&lt;p>Hibernate的工作流程：首先通过configuration对象读取配置文件；解析映射信息，创建StandardSessionFactory；调用openSession打开session；创建事务transaction，之后进行持久化操作；完成后提交事务，关闭session，关闭sessionFactory。&lt;/p>&lt;p>&lt;img class="" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" width="571" height="601" data-ratio="1.052539404553415" data-w="571" data-type="png" src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-fail="0">&lt;/p>&lt;p>&lt;strong>&amp;nbsp;Figuer 2 Hibernate工作流程&lt;/strong>&lt;/p>&lt;p>要理解ORM的理念：ORM意为对象关系映射。是一种为了解决程序的面向对象模型与数据库关系模型互不匹配问题的技术。&lt;/p>&lt;p>hibernate中比较重要的是对象的4种状态转换及条件。分别是transient瞬时态、persistent持久态、detached游离态和移除态，状态转换如下：&lt;/p>&lt;p>&lt;img class="" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" width="860" height="514" data-ratio="0.5976744186046512" data-w="860" data-type="png" src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-fail="0">&lt;/p>&lt;p>&lt;strong>&amp;nbsp;Figure 3 Hibernate对象状态转换图&lt;/strong>&lt;/p>&lt;h2>&lt;strong>Struts 2&lt;/strong>&lt;/h2>&lt;p>&lt;br>&lt;/p></description></item><item><title>转载自【 Java编程精选】一位程序员工作10年总结了这些忠告</title><link>https://pangyd.com/post/48-java10/</link><pubDate>Thu, 10 Aug 2017 19:46:59 +0800</pubDate><guid>https://pangyd.com/post/48-java10/</guid><description>&lt;p>展望未来，总结过去10年的程序员生涯，给程序员小弟弟小妹妹们的一些总结性忠告。&lt;/p>&lt;p>&lt;strong style="text-align: center">&lt;/strong>&lt;/p>&lt;p>&lt;span>1、自己的户口档案、养老保险、医疗保险、住房公积金一定要保管好。&lt;/span>&lt;/p>&lt;p>由 于程序员行业每年跳槽一次，我不隐瞒大家，我至少换过5个以上的单位，这期间跳来跳去，甚至是城市都换过3个。还好户口没丢掉，其他都已经是乱了，好几个 城市里，都有交过三金，甚至是一个程序的2个区里交的都有，那些东西，10年后，会变得很重要。你买房子若有公积金，可以取出来，贷款利率也会比较低一 些，有孩子了，还需要上学，生病了还需要医疗保险。&lt;/p>&lt;p>&lt;span>2、读&amp;gt;写代码&amp;gt;读&amp;gt;写代码（日复一日）&lt;/span>&lt;/p>&lt;p>关于如何高效学习编程我要给出的第一条建议是在阅读代码和编写代码之间循环往复。阅读代码（书籍，博客文章，开源代码）将帮助你查看解决方案，了解最佳做法，并大致了解语言或系统。但是在你这样做之后，你需要自己实际去写代码。可以是任何东西。可以是小的编码练习或业余项目，但确保你能将之付诸于实践，并用某种方式使用你学到的东西。如果你不这样做，那么你会发现自己面对编辑器会无所适从无从下手。&lt;/p>&lt;p>&lt;span>所有事情所花费的时间总是比你预期的要长&lt;/span>&lt;/p>&lt;p>特别是在编程中，即使一切进展顺利，我们也很难对功能所需的时间做出正确的预算。并且，开发软件时碰到各种意想不到的问题是非常常见的。一个简单的合并操作会导致一系列小bug，一次框架升级意味着一些函数必须改变或者一些API不按照你想象的那样工作。&lt;/p>&lt;blockquote>&lt;p>Hofstadter Law（ 霍夫施塔特定律）其实道出了真谛：做事所花费的时间总是比你预期的要长，即使你在预期中已经考虑了 Hofstadter Law（ 霍夫施塔特定律）。&lt;/p>&lt;/blockquote>&lt;p>&lt;span>先了解现有的代码&lt;/span>&lt;/p>&lt;p>大多数的编码都需要以某种方式改变现有的代码。即使是新功能，也需要适应现有的程序。所以，在你加进去新的内容前，首先需要了解当前的解决方案。否则，你一不小心就很有可能会打破现有的功能。这意味着，阅读代码和编写代码都是必要的技能。这也是为什么看似微小的变化仍可能需要很长时间才能解决的原因之一，因为你首先必须了解上下文。&lt;/p>&lt;p>&lt;span>成为开发者社区的一员&lt;/span>&lt;/p>&lt;p>当我还在大学的时候，我总是懒得参加各种社团和俱乐部活动。当我找到我的第一份开发工作时，最不乐意做的也是和其他开发者闲聊闲逛。&lt;/p>&lt;p>但是我错了。&lt;br>&lt;/p>&lt;p>同行聚会和进入开发群是很有趣的事情，是结识开发者伙伴的好地方。如果你想在这个行业里做到最好，就尽量不要消极被动。与坐在你旁边的人交谈，提供你的帮助，分享你的经验。每个人都喜欢谈论自己的经历，更何况你也许会遇到很多潜在的雇主。&lt;/p>&lt;p>在那里你会碰到许多需要教练的初学者团体，你可以指导新手，给他们提供练手的机会，甚至赞助活动。&lt;/p>&lt;p>当然，要学习别人的开发技巧并且勇于实践，要热情地欢迎不同意见的人讲话，勇敢地听取他们的意见。&lt;/p>&lt;p>&lt;span>编程并不是一件什么神秘的东西&lt;/span>&lt;/p>&lt;p>编程跟其他东西一样，是一门技术。跟语言学习一样，有需要掌握的语法和词汇；跟数学一样，有解决特定类型问题的流程方法；像各种工艺和艺术创作一样，有技术、工具以及人们经年累月发展起来的最佳实践方案，专门解决各种不同类型的任务，你可以自由的使用、修改或弃之不用。&lt;/p>&lt;p>但是编程也不是每个人都可以学好学懂学会的，曾经面试过从培训班出来的新人，一问三不知，最基本的知识点都模糊不清，一问他以前的专业职业，原来是高中没毕业，去了工厂做工人，觉得太辛苦，后来看到培训机构说没基础也可以学习编程，就把挣的钱全送给了培训机构去学习编程。结果呢？很清楚，他选择了不适合他的道路，注定没有出路。&lt;/p>&lt;p>虽然编程不神秘，但是它和美术、音乐、艺术、销售、设计等一样，也分人，也不是每个人都能学会都能干的。&lt;/p>&lt;p>&lt;span>这是一场马拉松，不是百米赛跑&lt;/span>&lt;/p>&lt;p>这三个月对我来说绝对不容易。这三个月，我每周都要辛苦六天用于找工作和学**。不过我还是把自己照顾得很好。&lt;/p>&lt;p>有的时候，我会和朋友一起学。有的时候，我会找个咖啡馆自己一个人学，或者去 Hack Reactor 提供的休息室学。每周我还会和教练报告我的进度。&lt;/p>&lt;p>在这个过程中很容易耗尽热情。那么就吃好，睡好，继续学。&lt;/p>&lt;p>而且会很容易感到孤单。和一群学友们在一起会好一点。&lt;/p>&lt;p>建议：要有长期作战的心理准备，照顾好自己的身体。&lt;/p>&lt;p>&lt;span>开发效率&lt;/span>&lt;/p>&lt;p>开发效率可以用这些方式提升：&lt;/p>&lt;p>1 . 构建公用工具类，方便大家使用&lt;/p>&lt;p>2 . 使用开源的一些包，例如 ORM 思想的数据库等&lt;/p>&lt;p>3 . 可以很快的找到问题。开发中，找 bug 的时间，往往是很多的。我用的方法有3个： 使用 try catch； 拦截所有 crash 到我指定的地方；超多的 Log，Log 有统一的控制开关。&lt;/p>&lt;p>4 . 借力：数据上报用灯塔，崩溃上报用 bugly，公司 KM 上很多经验，拿过来用&lt;/p></description></item><item><title>关于 JCombobox</title><link>https://pangyd.com/post/47-jcombobox/</link><pubDate>Wed, 09 Aug 2017 21:42:14 +0800</pubDate><guid>https://pangyd.com/post/47-jcombobox/</guid><description>&lt;p>&lt;span>构造函数&lt;/span>&lt;span>&amp;nbsp;&lt;/span>&lt;/p>&lt;span>JComboBox()&amp;nbsp;&lt;/span>&lt;br>&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 创建具有默认数据模型的 JComboBox。&amp;nbsp;&lt;/span>&lt;br>&lt;span>JComboBox(ComboBoxModel aModel)&amp;nbsp;&lt;/span>&lt;br>&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 创建一个 JComboBox，其项取自现有的 ComboBoxModel 中。&amp;nbsp;&lt;/span>&lt;br>&lt;span>JComboBox(Object[] items)&amp;nbsp;&lt;/span>&lt;br>&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 创建包含指定数组中的元素的 JComboBox。&amp;nbsp;&lt;/span>&lt;br>&lt;span>JComboBox(Vector&amp;lt;?&amp;gt; items)&amp;nbsp;&lt;/span>&lt;br>&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 创建包含指定 Vector 中的元素的 JComboBox。&amp;nbsp;&lt;/span>&lt;br>&lt;br>&lt;span>常用方法&amp;nbsp;&lt;/span>&lt;br>&lt;span>addActionListener(ActionListener l)&amp;nbsp;&lt;/span>&lt;br>&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 添加 ActionListener。&amp;nbsp;&lt;/span>&lt;br>&lt;span>addItem(Object anObject)&amp;nbsp;&lt;/span>&lt;br>&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 为项列表添加项。&amp;nbsp;&lt;/span>&lt;br>&lt;span>addItemListener(ItemListener aListener)&amp;nbsp;&lt;/span>&lt;br>&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 添加 ItemListener。&amp;nbsp;&lt;/span>&lt;br>&lt;span>configureEditor(ComboBoxEditor anEditor, Object anItem)&amp;nbsp;&lt;/span>&lt;br>&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 利用指定项初始化编辑器。&amp;nbsp;&lt;/span>&lt;br>&lt;span>getEditor()&amp;nbsp;&lt;/span>&lt;br>&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 返回用于绘制和编辑 JComboBox 字段中所选项的编辑器。&amp;nbsp;&lt;/span>&lt;br>&lt;span>getItemAt(int index)&amp;nbsp;&lt;/span>&lt;br>&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 返回指定索引处的列表项。&amp;nbsp;&lt;/span>&lt;br>&lt;span>getItemCount()&amp;nbsp;&lt;/span>&lt;br>&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 返回列表中的项数。&amp;nbsp;&lt;/span>&lt;br>&lt;span>getModel()&amp;nbsp;&lt;/span>&lt;br>&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 返回 JComboBox 当前使用的数据模型。&amp;nbsp;&lt;/span>&lt;br>&lt;span>getRenderer()&amp;nbsp;&lt;/span>&lt;br>&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 返回用于显示 JComboBox 字段中所选项的渲染器。&amp;nbsp;&lt;/span>&lt;br>&lt;span>getSelectedIndex()&amp;nbsp;&lt;/span>&lt;br>&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 返回列表中与给定项匹配的第一个选项。&amp;nbsp;&lt;/span>&lt;br>&lt;span>getSelectedItem()&amp;nbsp;&lt;/span>&lt;br>&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 返回当前所选项。&amp;nbsp;&lt;/span>&lt;br>&lt;span>insertItemAt(Object anObject, int index)&amp;nbsp;&lt;/span>&lt;br>&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 在项列表中的给定索引处插入项。&amp;nbsp;&lt;/span>&lt;br>&lt;span>isEditable()&amp;nbsp;&lt;/span>&lt;br>&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 如果 JComboBox 可编辑，则返回 true。&amp;nbsp;&lt;/span>&lt;br>&lt;span>removeAllItems()&amp;nbsp;&lt;/span>&lt;br>&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 从项列表中移除所有项。&amp;nbsp;&lt;/span>&lt;br>&lt;span>removeItem(Object anObject)&amp;nbsp;&lt;/span>&lt;br>&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 从项列表中移除项。&amp;nbsp;&lt;/span>&lt;br>&lt;span>removeItemAt(int anIndex)&amp;nbsp;&lt;/span>&lt;br>&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 移除 anIndex 处的项。&amp;nbsp;&lt;/span>&lt;br>&lt;span>setModel(ComboBoxModel aModel)&amp;nbsp;&lt;/span>&lt;br>&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 设置 JComboBox 用于获取项列表的数据模型。&amp;nbsp;&lt;/span>&lt;br>&lt;span>setRenderer(ListCellRenderer aRenderer)&amp;nbsp;&lt;/span>&lt;br>&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 设置渲染器，该渲染器用于绘制列表项和从 JComboBox 字段的列表中选择的项。&amp;nbsp;&lt;/span>&lt;br>&lt;span>setSelectedIndex(int anIndex)&amp;nbsp;&lt;/span>&lt;br>&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 选择索引 anIndex 处的项。&amp;nbsp;&lt;/span>&lt;br>&lt;span>setSelectedItem(Object anObject)&amp;nbsp;&lt;/span>&lt;br>&lt;span>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 将组合框显示区域中所选项设置为参数中的对象&lt;/span></description></item><item><title>基本上写完人事管理系统的感受</title><link>https://pangyd.com/post/46/</link><pubDate>Wed, 09 Aug 2017 21:01:53 +0800</pubDate><guid>https://pangyd.com/post/46/</guid><description>&lt;p>总共写了6天 &amp;nbsp;一个字累 但是坚持了下来 为了下个学期的Java web &amp;nbsp;&lt;/p>&lt;p>知识点总结：&lt;/p>&lt;p>Statement：用于执行静态sql语句 并返回它所生成的结果（定义成私有变量）&lt;/p>&lt;p>ResultSet ：结果集类&lt;/p>&lt;p>Connection：链接类&amp;nbsp;&lt;/p>&lt;p>"jdbc:mysql://localhost:3306/db_hrms"：数据库链接地址字符串 前面定义为字符型&lt;/p>&lt;p>characterEncoding=GBK:防止乱码&lt;/p>&lt;p>Class.forName("com.mysql.jdbc.Driver");：连接驱动字符串&lt;/p>&lt;p>{&lt;/p>&lt;p>&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; conn=(Connection) DriverManager.getConnection(strurl, username, password); ：conn用于连接数据库 分别为地址 用户名 密码&lt;/p>&lt;p>&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; DriverManager.getConnection： 启动器管理类的连接方法&lt;/p>&lt;p>}try方法&lt;/p>&lt;p>commit():该方法用于修改传入的结果 放进数据库&lt;/p>&lt;p>insert into Person() values(）; insert：插入 &amp;nbsp;into: 进入中 Person() 表 &amp;nbsp;values 数据 ：字面意思&lt;/p>&lt;p>update Person set * 修改 person表中的 设置 后面跟 表中字符加修改字符&lt;/p>&lt;p>delete from Person where PersonID 删除&lt;/p></description></item><item><title>Node11Panel类 添加人员信息操作</title><link>https://pangyd.com/post/45-node11panel/</link><pubDate>Tue, 08 Aug 2017 19:16:47 +0800</pubDate><guid>https://pangyd.com/post/45-node11panel/</guid><description>&lt;pre lay-lang="Java" class="layui-code" skin="notepad">package com.jnzyjsxy.node1;

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;

import com.jnzyjsxy.common.DeptBean;
import com.jnzyjsxy.common.PersonBean;
import com.jnzyjsxy.test.HrMain;

/*
 * 第一个节点
 * 添加人员信息
 */
public class Node11Panel extends JPanel implements ActionListener,ItemListener{
	
	//创建两个面板 一个中间面板 一个上部面板
	JPanel centerPanel=new JPanel();
	JPanel upPanel=new JPanel();
	//定义图形元素
	JLabel jLabel = new JLabel();
	JLabel jLabel1 = new JLabel();
	JLabel jLabel2 = new JLabel();
	JLabel jLabel3 = new JLabel();
	JLabel jLabel4 = new JLabel();
	JLabel jLabel5 = new JLabel();
	JLabel jLabel6 = new JLabel();
	JLabel jLabel7 = new JLabel();
	JLabel jLabel8 = new JLabel();
	JLabel jLabel9 = new JLabel();
	
	JTextField jTextField1 =new JTextField(15);//编号
	JTextField jTextField2 =new JTextField(15);//姓名
	JTextField jTextField3 =new JTextField(15);//性别
	JTextField jTextField4 =new JTextField(15);//出生年月
	JTextField jTextField5 =new JTextField(15);//民族
	JTextField jTextField6 =new JTextField(15);//地址
	
	JComboBox jComboBox1=null;//显示人员所在部门
	String DeptID="1";//部门编号
	String Salary="0";//薪酬
	String Assess="未考核";//考核
	//用于输入其他字段值
	JTextField jTextField8=new JTextField(15);
	
	JScrollPane jScrollPane;
	//创建按钮 本页面使用addInfo clearInfo 
	//为了实现页面复制 定义多个按钮 哪个页面需要 使用哪个按钮
	JButton addInfo=new JButton();
	JButton modifyInfo=new JButton();
	JButton deleteInfo=new JButton();
	JButton clearInfo=new JButton();
	//创建网格包布局对象
	GridBagLayout girdBag=new GridBagLayout();
	//创建网格包约束类变量
	GridBagConstraints girdBagCon;
	//创建PersonBean 人员数据操作类
	PersonBean bean=new PersonBean();
	
	public Node11Panel() {
		// TODO Auto-generated constructor stub
		//采用边框布局
		this.setLayout(new BorderLayout());
		try {
			jscrollPanelInit();//上部面板初始
			panelInit();//中间面板初始化
			addListener();//监听事件方法
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}
	/*
	 * jscrollpanel 面板的布局 包含放置组件的中间面板centerPanel
	 * (non-Javadoc)
	 * @see java.awt.event.ItemListener#itemStateChanged(java.awt.event.ItemEvent)
	 */
	public void jscrollPanelInit() {
		//中间放组件的面板 采用网格包布局
		centerPanel.setLayout(girdBag);
		//第一行组件
		//griy=1 实际的第二行 显示4个组件 gridx依次增加
		jLabel1.setText("人员编号");
		jLabel1.setFont(new Font("Dialog", 0, 12));
		girdBagCon=new GridBagConstraints();
		girdBagCon.gridx=0;
		girdBagCon.gridy=1;
		//外部填充 4个参数 top,left,bottom,right
		//既外部间距
		girdBagCon.insets=new Insets(0, 10, 10, 1);
		girdBag.setConstraints(jLabel1, girdBagCon);
		centerPanel.add(jLabel1);
		
		girdBagCon=new GridBagConstraints();
		girdBagCon.gridx=1;
		girdBagCon.gridy=1;
		girdBagCon.insets=new Insets(0, 1, 10, 15);
		girdBag.setConstraints(jTextField1, girdBagCon);
		centerPanel.add(jTextField1);
		
		jLabel2.setText("人员姓名");
		jLabel2.setFont(new Font("Dialog", 0, 12));
		girdBagCon=new GridBagConstraints();
		girdBagCon.gridx=2;
		girdBagCon.gridy=1;
		//外部填充 4个参数 top,left,bottom,right
		//既外部间距
		girdBagCon.insets=new Insets(0, 15, 10, 1);
		girdBag.setConstraints(jLabel2, girdBagCon);
		centerPanel.add(jLabel2);
		
		girdBagCon=new GridBagConstraints();
		girdBagCon.gridx=3;
		girdBagCon.gridy=1;
		girdBagCon.insets=new Insets(0, 1, 10, 10);
		girdBag.setConstraints(jTextField2, girdBagCon);
		centerPanel.add(jTextField2);
		
		jLabel3.setText("性 别");
		jLabel3.setFont(new Font("Dialog", 0, 12));
		girdBagCon=new GridBagConstraints();
		girdBagCon.gridx=0;
		girdBagCon.gridy=2;
		//外部填充 4个参数 top,left,bottom,right
		//既外部间距
		girdBagCon.insets=new Insets(10, 10, 10, 1);
		girdBag.setConstraints(jLabel3, girdBagCon);
		centerPanel.add(jLabel3);
		
		girdBagCon=new GridBagConstraints();
		girdBagCon.gridx=1;
		girdBagCon.gridy=2;
		girdBagCon.insets=new Insets(10, 1, 10, 15);
		girdBag.setConstraints(jTextField3, girdBagCon);
		centerPanel.add(jTextField3);
		
		jLabel4.setText("出 生 年 月");
		jLabel4.setFont(new Font("Dialog", 0, 12));
		girdBagCon=new GridBagConstraints();
		girdBagCon.gridx=2;
		girdBagCon.gridy=2;
		//外部填充 4个参数 top,left,bottom,right
		//既外部间距
		girdBagCon.insets=new Insets(10, 15, 10, 1);
		girdBag.setConstraints(jLabel4, girdBagCon);
		centerPanel.add(jLabel4);
		
		girdBagCon=new GridBagConstraints();
		girdBagCon.gridx=3;
		girdBagCon.gridy=2;
		girdBagCon.insets=new Insets(10, 1, 10, 10);
		girdBag.setConstraints(jTextField4, girdBagCon);
		centerPanel.add(jTextField4);
		
		jLabel5.setText("民		族");
		jLabel5.setFont(new Font("Dialog", 0, 12));
		girdBagCon=new GridBagConstraints();
		girdBagCon.gridx=0;
		girdBagCon.gridy=3;
		//外部填充 4个参数 top,left,bottom,right
		//既外部间距
		girdBagCon.insets=new Insets(10, 10, 10, 1);
		girdBag.setConstraints(jLabel5, girdBagCon);
		centerPanel.add(jLabel5);
		
		girdBagCon=new GridBagConstraints();
		girdBagCon.gridx=1;
		girdBagCon.gridy=3;
		girdBagCon.insets=new Insets(10, 1, 10, 15);
		girdBag.setConstraints(jTextField5, girdBagCon);
		centerPanel.add(jTextField5);
		
		jLabel6.setText("地		址");
		jLabel6.setFont(new Font("Dialog", 0, 12));
		girdBagCon=new GridBagConstraints();
		girdBagCon.gridx=2;
		girdBagCon.gridy=3;
		//外部填充 4个参数 top,left,bottom,right
		//既外部间距
		girdBagCon.insets=new Insets(10, 15, 10, 1);
		girdBag.setConstraints(jLabel6, girdBagCon);
		centerPanel.add(jLabel6);
		
		girdBagCon=new GridBagConstraints();
		girdBagCon.gridx=3;
		girdBagCon.gridy=3;
		girdBagCon.insets=new Insets(10, 1, 10, 10);
		girdBag.setConstraints(jTextField6, girdBagCon);
		centerPanel.add(jTextField6);
		
		//第四行显示组件 gridy=4 gridx 依次增加
		jLabel7.setText("部		门");
		jLabel7.setFont(new Font("Dialog", 0, 12));
		girdBagCon=new GridBagConstraints();
		girdBagCon.gridx=0;
		girdBagCon.gridy=4;
		//外部填充 4个参数 top,left,bottom,right
		//既外部间距
		girdBagCon.insets=new Insets(10, 10, 10, 1);
		girdBag.setConstraints(jLabel7, girdBagCon);
		centerPanel.add(jLabel7);
		
		//定义部门操作类
		DeptBean dBean=new DeptBean();
		//调用方法获取所有部门的字符串
		String[] alltype=dBean.searchAllForNode();
		jComboBox1=new JComboBox(alltype);
		
		girdBagCon=new GridBagConstraints();
		girdBagCon.gridx=1;
		girdBagCon.gridy=4;
		//girdBagCon.gridwidth=3;
		//girdBagCon.gridheight=1;
		girdBagCon.insets=new Insets(10, 1, 10, 15);
		girdBag.setConstraints(jComboBox1, girdBagCon);
		centerPanel.add(jComboBox1);
				
		jLabel8.setText("其		他");
		jLabel8.setFont(new Font("Dialog", 0, 12));
		girdBagCon=new GridBagConstraints();
		girdBagCon.gridx=2;
		girdBagCon.gridy=4;
		//外部填充 4个参数 top,left,bottom,right
		//既外部间距
		girdBagCon.insets=new Insets(10, 0, 10, 1);
		girdBag.setConstraints(jLabel8, girdBagCon);
		centerPanel.add(jLabel8);
		
		girdBagCon=new GridBagConstraints();
		girdBagCon.gridx=3;
		girdBagCon.gridy=4;
		girdBagCon.gridwidth=3;
		girdBagCon.gridheight=1;
		girdBagCon.insets=new Insets(10, 1, 10, 15);
		girdBag.setConstraints(jTextField8, girdBagCon);
		centerPanel.add(jTextField8);
		
		addInfo.setText("增加");
		addInfo.setFont(new Font("Dialog", 0, 12));
		girdBagCon=new GridBagConstraints();
		girdBagCon.gridx=0;
		girdBagCon.gridy=5;
		girdBagCon.gridwidth=2;
		girdBagCon.gridheight=1;
		//外部填充 4个参数 top,left,bottom,right
		//既外部间距
		girdBagCon.insets=new Insets(10, 10, 10, 10);
		girdBag.setConstraints(addInfo, girdBagCon);
		centerPanel.add(addInfo);
		
		
		
		clearInfo.setText("清空");
		clearInfo.setFont(new Font("Dialog", 0, 12));
		girdBagCon=new GridBagConstraints();
		girdBagCon.gridx=2;
		girdBagCon.gridy=5;
		girdBagCon.gridwidth=2;
		girdBagCon.gridheight=1;
		//外部填充 4个参数 top,left,bottom,right
		//既外部间距
		girdBagCon.insets=new Insets(10, 10, 10, 10);
		girdBag.setConstraints(clearInfo, girdBagCon);
		centerPanel.add(clearInfo);

	}
	
	//上部面板初始化
	public void panelInit() {
		//上部面板，网格包布局
		upPanel.setLayout(girdBag);
		//上部包含泽增加人员信息标签和滚动面板
		jLabel.setText("增加人员信息");
		jLabel.setFont(new Font("Dialog", 0, 16));
		girdBagCon=new GridBagConstraints();
		girdBagCon.gridx=0;
		girdBagCon.gridy=0;
		//外部填充 4个参数 top,left,bottom,right
		//既外部间距
		girdBagCon.insets=new Insets(0, 10, 0, 10);
		girdBag.setConstraints(jLabel, girdBagCon);
		upPanel.add(jLabel);
		
		//滚动面板 包含组件的中间，面板在滚动面板上
		jScrollPane =new JScrollPane(centerPanel);
		jScrollPane.setPreferredSize(new Dimension(450,380));
		girdBagCon=new GridBagConstraints();
		girdBagCon.gridx=0;
		girdBagCon.gridy=1;
		//外部填充 4个参数 top,left,bottom,right
		//既外部间距
		girdBagCon.insets=new Insets(0, 0, 0, 0);
		girdBag.setConstraints(jScrollPane, girdBagCon);
		upPanel.add(jScrollPane);
		
		//上部面板添加到窗体
		this.add(upPanel,BorderLayout.NORTH);
		//设置人员编号文本框不可用
		jTextField1.setEditable(false);
		jTextField2.setEditable(true);
		jTextField3.setEditable(true);
		jTextField4.setEditable(true);
		jTextField5.setEditable(true);
		jTextField6.setEditable(true);
		jTextField8.setEditable(true);
		jTextField1.setText(""+bean.getId());
		
	}
	/*添加事件监听
	 * (non-Javadoc)
	 * @see java.awt.event.ItemListener#itemStateChanged(java.awt.event.ItemEvent)
	 */
	public void addListener() {
		//添加添加，清空按钮事件监听
		addInfo.addActionListener(this);
		clearInfo.addActionListener(this);
		//给显示部门的下拉列表添加项目选择监听
		//既当在下拉列表框中选择项目后 触发监听
		jComboBox1.addItemListener(this);
		
	}
	@Override
	public void itemStateChanged(ItemEvent e) {
		// TODO Auto-generated method stub
		//ItemEvent--项目事件，例如下拉列表框中项被选定或取消选定的事件 
		//e.getStateChange()--表示选定或取消选定 
		//ItemEvent.SELECTED--表示选定 
		//ItemEvent.DESELECTED--表示取消选定 
		//如果在下拉列表框中选中一个部门 
		if (e.getStateChange()==ItemEvent.SELECTED) {
			//获取选中项目值，得到的是一个“1-办公室-秘书室”这样的字符串 
			//字符串构成：部门编号-一级部门-二级部门 
			String temStr=""+e.getItem();
			//返回指定子字符串"-"在此字符串中第一次出现处的索引 
			int i=temStr.indexOf("-");
			 //取部门id子字符串，目的是取前面的部门编号 
			DeptID=temStr.substring(0,i);
		}
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		Object obj=e.getSource();
		if (obj==addInfo) {//增加
			//调用Personean的add()方法 实现添加纪录
			bean.add(jTextField1.getText(), jTextField2.getText(), jTextField3.getText(), jTextField4.getText(), jTextField5.getText(), jTextField6.getText(), DeptID, Salary, Assess, jTextField8.getText());
			//定义添加人员信息页面对象
			Node11Panel node11Panel=new Node11Panel();
			//用添加人员信息作为右侧组件
			HrMain.splitPane.setRightComponent(node11Panel);
		}
		else if (obj==clearInfo) {
			setNull();//调用清空方法
		}
	}
	void setNull(){
		jTextField2.setText(null);
		jTextField3.setText(null);
		jTextField4.setText(null);
		jTextField5.setText(null);
		jTextField6.setText(null);
		jTextField8.setText(null);
	}

}
&lt;/pre></description></item><item><title>系统运行主类HrP.java（包含main）和主界面类HrMain.java 1. 系统运行主类HrMS.java，包含main方法。</title><link>https://pangyd.com/post/44-hrp-java-main-hrmain-java-1-hrms-java-main/</link><pubDate>Tue, 08 Aug 2017 19:16:10 +0800</pubDate><guid>https://pangyd.com/post/44-hrp-java-main-hrmain-java-1-hrms-java-main/</guid><description>&lt;pre lay-lang="Java" class="layui-code" skin="notepad">package com.jnzyjsxy.test;

import java.awt.Dimension;
import java.awt.Toolkit;

import javax.swing.UIManager;

/*
 * 人事管理运行主类
 */
public class HrP {
	//定义布尔型变量
	boolean packFame=false;
	//构造方法
	public HrP() {
		// TODO Auto-generated constructor stub
		//创建主窗体类对象
		HrMain frame=new HrMain();
		if (packFame) {
			//窗口自适应大小 使窗口正好显示里面的控件
			frame.pack();
		}else {
			//使用validate方法 会使容器再次布置其子控件
			frame.validate();
		}
		//获取屏幕大小
		Dimension screenSize=Toolkit.getDefaultToolkit().getScreenSize();
		//获取当前项目的窗体大小
		Dimension frameSize=frame.getSize();
		//如果项目窗体高&amp;gt;屏幕高，用屏幕高设置项目窗体高
		if (frameSize.height&amp;gt;screenSize.height) {
			frameSize.height=screenSize.height;
		}
		if (frameSize.width&amp;gt;screenSize.width) {
			frameSize.width=screenSize.width;
		}
		//设置窗体起始显示位置 居中显示
		frame.setLocation((screenSize.width-frameSize.width)/2,
		(screenSize.height-frameSize.height)/2);
		//显示窗体
		frame.setVisible(true);
	}
	public static void main(String[] args) {
		 //设置运行风格
		try {
			//UIManager--界面管理类
			//外观设置成所使用的操作平台的外观
			//即程序在哪个平台运行，显示的窗口，对话框将是哪个平台的外观
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
		//创建主类对象测试项目
		new HrP();
	}
}
&lt;/pre></description></item><item><title>HrMain.java系统主界面类，采用树形目录结构。</title><link>https://pangyd.com/post/43-hrmain-java/</link><pubDate>Tue, 08 Aug 2017 19:14:37 +0800</pubDate><guid>https://pangyd.com/post/43-hrmain-java/</guid><description>&lt;p>&lt;/p>&lt;pre lay-lang="Java" class="layui-code" skin="notepad">package com.jnzyjsxy.test;
&lt;p>import java.awt.AWTError;
import java.awt.AWTEvent;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Panel;
import java.awt.Toolkit;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.net.URL;
import java.net.URLClassLoader;&lt;/p>
&lt;p>import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
/*&lt;/p>
&lt;ul>
&lt;li>人事管理系统主界面
*/
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;&lt;/li>
&lt;/ul>
&lt;p>import com.jnzyjsxy.node1.Node11Panel;
public class HrMain extends JFrame implements TreeSelectionListener{
private static final URLClassLoader URLClassLoader = null;
//框架大小
Dimension faceSize=new Dimension(650, 450);
//程序图标
Image icon;
//建立JTree目录树对象
JTree tree;
//书数据结构中的通用节点
//字面含义，默认可变的树节点类
DefaultMutableTreeNode root;//人事管理系统根节点
DefaultMutableTreeNode node1;//基本信息管理
DefaultMutableTreeNode node2;//人员管理节点
DefaultMutableTreeNode node3;//人员考核管理
DefaultMutableTreeNode node4;//劳资管理
DefaultMutableTreeNode node5;//
DefaultMutableTreeNode leafnode;//二级节点
TreePath treePath;//节点路径类
//主界面面板
//JSplitPane 用于分割两个（只能是两个）Component
//两个Component图形化分割
//并且这两个Component可以由用户交互式调整大小
//split&amp;ndash;分裂，拆分
public static JSplitPane splitPane;
JPanel panel1;//在左侧放目录树
JPanel panel2;
JPanel panel3;//在右侧显示选择节点后的界面
//用于显示欢迎信息的标签
JLabel welcome=new JLabel();
//滚动面板对象
JScrollPane scrollPane;
/*
* 构造方法(non-Javadoc)
* @see java.awt.Window#pack()
&lt;em>/public HrMain() {
// TODO Auto-generated constructor stub
//启动窗体事件隐藏 mask-面具，隐藏
//要是没有enableEvents(AWTEvent.WIDOW_EVENT_MASK);
//只要有addActionListener()方法，窗体也就拥有该方法
//本项目通过选择目录树触发活动事件
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
//添加框架的关闭时间处理
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//窗口自适应大小 使窗体能正好显示里面的所有控件
this.pack();
//设置框架的大小
this.setSize(faceSize);
//设置窗体的标题
this.setTitle(&amp;ldquo;人事管理系统&amp;rdquo;);
//调用自定义的方法GetImage（） ，获取图标文件
//icon=getImage(&amp;ldquo;common/icon.png&amp;rdquo;);
//设置窗体图标
this.setIconImage(icon);
//设置不能调整窗体的大小
this.setResizable(false);
try {
Init();//调用初始化方法
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
/&lt;/em>
* 初始化方法 创建左侧菜单树
*/
private void Init() {
// TODO Auto-generated method stub
//初始化树形节点
root=new DefaultMutableTreeNode(&amp;ldquo;人事管理系统&amp;rdquo;);
node1=new DefaultMutableTreeNode(&amp;ldquo;基本信息管理&amp;rdquo;);
node2=new DefaultMutableTreeNode(&amp;ldquo;人员调动管理&amp;rdquo;);
node3=new DefaultMutableTreeNode(&amp;ldquo;人员考核管理&amp;rdquo;);
node4=new DefaultMutableTreeNode(&amp;ldquo;劳资管理&amp;rdquo;);
//添加基本信息管理节点到认识管里系统根节点
root.add(node1);
//添加耳机节点 并添加到基本信息管理一级节点上
leafnode=new DefaultMutableTreeNode(&amp;ldquo;添加人员信息&amp;rdquo;);
node1.add(leafnode);
leafnode=new DefaultMutableTreeNode(&amp;ldquo;修改人员信息&amp;rdquo;);
node1.add(leafnode);
leafnode=new DefaultMutableTreeNode(&amp;ldquo;删除人员信息&amp;rdquo;);
node1.add(leafnode);
leafnode=new DefaultMutableTreeNode(&amp;ldquo;查询人员信息&amp;rdquo;);
node1.add(leafnode);
leafnode=new DefaultMutableTreeNode(&amp;ldquo;部门管理&amp;rdquo;);
node1.add(leafnode);
//添加人员调动节点到根节点
root.add(node2);
leafnode=new DefaultMutableTreeNode(&amp;ldquo;人员调动&amp;rdquo;);
node2.add(leafnode);
leafnode=new DefaultMutableTreeNode(&amp;ldquo;调动历史查询&amp;rdquo;);
node2.add(leafnode);
root.add(node3);
leafnode=new DefaultMutableTreeNode(&amp;ldquo;人员考核&amp;rdquo;);
node3.add(leafnode);
leafnode=new DefaultMutableTreeNode(&amp;ldquo;考核历史查询&amp;rdquo;);
node3.add(leafnode);&lt;/p></description></item><item><title>HistrinBean.java 类，用亍实现对历史流水相关信息进行数据库操作的功 能，包括增加流水信息、提供多种方式的查询等</title><link>https://pangyd.com/post/42-histrinbean-java/</link><pubDate>Tue, 08 Aug 2017 19:11:26 +0800</pubDate><guid>https://pangyd.com/post/42-histrinbean-java/</guid><description>&lt;pre lay-lang="Java" class="layui-code" skin="notepad">package com.jnzyjsxy.common;

import java.sql.ResultSet;

import javax.swing.JOptionPane;

public class HistrinBean {
	//定义字符串用于存储sql字符串
		String sql;
		//结果集类
		ResultSet rs=null;
		//声明字符串变量 存储从操作界面传过来的人员信息
		String field1;
		String field2;
		String field3;
		String field4;
		String field5;
		String field6;
		String field7;
		public void add(String f1,String f2,String f3,String f4,String f5,
				String f6,String f7){
			//创建数据库对象 执行数据库里面的方法 链接数据库 执行sql语句
			Database DB=new Database();
			//将从添加界面传过来的值 付给成员变量
			this.field1=f1;
			this.field2=f2;
			this.field3=f3;
			this.field4=f4;
			this.field5=f5;
			this.field6=f6;
			this.field7=f7;
			//判断穿过来的值是否为空 如果为空就显示提示语句
			if (field2==null || field2.equals("")) {
				JOptionPane.showMessageDialog(null, "请输入FromAcc", "错误", JOptionPane.ERROR_MESSAGE);
				return;
			}
			else if (field3==null||field3.equals("")) {
				JOptionPane.showMessageDialog(null,"请输入OldInfo","错误",
						JOptionPane.ERROR_MESSAGE);
				return;
			}
			else if (field4==null||field4.equals("")) {
				JOptionPane.showMessageDialog(null,"请输入NewInfo","错误",
						JOptionPane.ERROR_MESSAGE);
				return;
			}
			else if (field5==null||field5.equals("")) {
				JOptionPane.showMessageDialog(null,"请输入ChgTime","错误",
						JOptionPane.ERROR_MESSAGE);
				return;
			}
			else if (field6==null||field6.equals("")) {
				JOptionPane.showMessageDialog(null,"请输入RegDate","错误",
						JOptionPane.ERROR_MESSAGE);
				return;
			}
			else if (field7==null||field7.equals("")) {
				JOptionPane.showMessageDialog(null,"请输入PersonID","错误",
						JOptionPane.ERROR_MESSAGE);
				return;
			}
			//构建插入字符串
			//构建sql字符串时，注意字符型，两侧用单引号做定界符，int,float不用定界符
			//传递过来的数据是字符型， 
			//为了插入int数据，进行类型转换-Integer.parseInt(field1)
			else {
				sql="insert into Histrjn( b,PersonID) values("+Integer.parseInt(field1)+ ",'"+field2+"','"+field3+"','"+field4+"',"+Integer.parseInt(field5)+",'"+field6+"',"+Integer.parseInt(field7)+")";
				System.out.println(sql);	
				//打开数据库连接
				try {
					DB.openConn();
					//执行sql语句
					DB.executeUpdate(sql);
					//提示信息
					JOptionPane.showMessageDialog(null, "你成功添加一条新的纪录");
				} catch (Exception e) {
					// TODO: handle exception
					//出现异常 ，给出提示
					System.out.println(e);
					JOptionPane.showMessageDialog(null, "保存失败 ","错误！", JOptionPane.ERROR_MESSAGE);
				}
					//关闭语句对象和链接对象
					finally{
						DB.closeStmt();
						DB.closeConn();
					}
				}
		}
			/*
			 * 根据JourNo
			 * ，返回人员信息各列值组成的字符数组
			 */
			public String[] search(String f1) {
				Database DB=new Database();
				this.field1=f1;
				//创建字符串数组 用于记录查询的数据
				String[] s =new String[6];
				sql="select * from Histrjn where JourNo="+field1;
				try{
					DB.openConn();//连接数据库
					//执行查询，查询结果付给rs，rs为结果集
					rs=DB.executeQuery(sql);
					//如果rs.next为true
					if (rs.next()) {
						//获取指定的值
						//说明：PersonID'DeptId salary均不是String类型
						//但在此简化处理，把取出值看作字符串，赋值给字符数组元素
						//方便统一待会返回值
						s[0]=rs.getString("JourNo");
						s[1]=rs.getString("FromAcc");
						s[2]=rs.getString("OldInfo");
						s[3]=rs.getString("NewInfo");
						s[4]=rs.getString("ChgTime");
						s[5]=rs.getString("RegDate");
						s[6]=rs.getString("PersonID");
					}else {
						s=null;
					}
				}catch(Exception e){
					
				}finally {
						DB.closeStmt();
						DB.closeConn();
					}
				return s;
				}
			/*
			 * 根据PersonID
			 * ，返回人员信息各列值组成的字符数组
			 */
			public String[] searchPI(String f7) {
				Database DB=new Database();
				this.field1=f7;
				//创建字符串数组 用于记录查询的数据
				String[] s =new String[6];
				sql="select * from Histrjn where PersonID="+field7;
				try{
					DB.openConn();//连接数据库
					//执行查询，查询结果付给rs，rs为结果集
					rs=DB.executeQuery(sql);
					//如果rs.next为true
					if (rs.next()) {
						//获取指定的值
						//说明：PersonID'DeptId salary均不是String类型
						//但在此简化处理，把取出值看作字符串，赋值给字符数组元素
						//方便统一待会返回值
						s[0]=rs.getString("JourNo");
						s[1]=rs.getString("FromAcc");
						s[2]=rs.getString("OldInfo");
						s[3]=rs.getString("NewInfo");
						s[4]=rs.getString("ChgTime");
						s[5]=rs.getString("RegDate");
						s[6]=rs.getString("PersonID");
					}else {
						s=null;
					}
				}catch(Exception e){
					
				}finally {
						DB.closeStmt();
						DB.closeConn();
					}
				return s;
				}
			}
		

&lt;/pre></description></item><item><title>外观设置成所使用的操作平台的外观即程序在哪个平台运行，显示的窗口，对话框将是哪个平台的外观</title><link>https://pangyd.com/post/41/</link><pubDate>Mon, 07 Aug 2017 18:57:57 +0800</pubDate><guid>https://pangyd.com/post/41/</guid><description>&lt;pre lay-lang="Java" class="layui-code" skin="notepad"> //UIManager--界面管理类
			//外观设置成所使用的操作平台的外观
			//即程序在哪个平台运行，显示的窗口，对话框将是哪个平台的外观
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());&lt;/pre></description></item><item><title>用于测试数据库连接情况</title><link>https://pangyd.com/post/40/</link><pubDate>Mon, 07 Aug 2017 13:41:34 +0800</pubDate><guid>https://pangyd.com/post/40/</guid><description>&lt;pre lay-lang="Java" class="layui-code" skin="notepad">package com.jnzyjsxy.test;

import com.jnzyjsxy.common.Database;
import com.jnzyjsxy.common.DeptBean;
import com.jnzyjsxy.common.HistrinBean;
import com.jnzyjsxy.common.PersonBean;

public class Text {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//PersonBean personBean=new PersonBean();
		//personBean.add("7","庞玉栋", "男", "1998-1-19", "汉", "", "7", "1900.23", "优秀",null);
		//personBean.updateDept("5", "2000.0");
		//String[][] strings=personBean.searchAll();
		//System.out.println(strings[0][2]);
		//String f1 = "1";
		//personBean.delete(f1);
		//DeptBean deptBean=new DeptBean();
		//String[] strings=deptBean.search("7");
		//System.out.print(strings[0]+".");
		//System.out.print(strings[1]+".");
		//System.out.print(strings[2]);
		//System.out.println(deptBean.getDepstr("1"));
		HistrinBean histrinBean=new HistrinBean();
		String[] string=null;
		//histrinBean.add("13", "人员分配", "2", "4", "1", "1", "1");
		string=histrinBean.search("1");
		System.out.println(string[4]);
	}
	

}
&lt;/pre></description></item><item><title>人事管理系统——Histrjn表增删改查操作类</title><link>https://pangyd.com/post/39-histrjn/</link><pubDate>Mon, 07 Aug 2017 13:37:08 +0800</pubDate><guid>https://pangyd.com/post/39-histrjn/</guid><description>&lt;pre lay-lang="Java" class="layui-code" skin="notepad">package com.jnzyjsxy.common;

import java.sql.ResultSet;

import javax.swing.JOptionPane;

public class HistrinBean {
	//定义字符串用于存储sql字符串
		String sql;
		//结果集类
		ResultSet rs=null;
		//声明字符串变量 存储从操作界面传过来的人员信息
		String field1;
		String field2;
		String field3;
		String field4;
		String field5;
		String field6;
		String field7;
		public void add(String f1,String f2,String f3,String f4,String f5,
				String f6,String f7){
			//创建数据库对象 执行数据库里面的方法 链接数据库 执行sql语句
			Database DB=new Database();
			//将从添加界面传过来的值 付给成员变量
			this.field1=f1;
			this.field2=f2;
			this.field3=f3;
			this.field4=f4;
			this.field5=f5;
			this.field6=f6;
			this.field7=f7;
			//判断穿过来的值是否为空 如果为空就显示提示语句
			if (field2==null || field2.equals("")) {
				JOptionPane.showMessageDialog(null, "请输入FromAcc", "错误", JOptionPane.ERROR_MESSAGE);
				return;
			}
			else if (field3==null||field3.equals("")) {
				JOptionPane.showMessageDialog(null,"请输入OldInfo","错误",
						JOptionPane.ERROR_MESSAGE);
				return;
			}
			else if (field4==null||field4.equals("")) {
				JOptionPane.showMessageDialog(null,"请输入NewInfo","错误",
						JOptionPane.ERROR_MESSAGE);
				return;
			}
			else if (field5==null||field5.equals("")) {
				JOptionPane.showMessageDialog(null,"请输入ChgTime","错误",
						JOptionPane.ERROR_MESSAGE);
				return;
			}
			else if (field6==null||field6.equals("")) {
				JOptionPane.showMessageDialog(null,"请输入RegDate","错误",
						JOptionPane.ERROR_MESSAGE);
				return;
			}
			else if (field7==null||field7.equals("")) {
				JOptionPane.showMessageDialog(null,"请输入PersonID","错误",
						JOptionPane.ERROR_MESSAGE);
				return;
			}
			//构建插入字符串
			//构建sql字符串时，注意字符型，两侧用单引号做定界符，int,float不用定界符
			//传递过来的数据是字符型， 
			//为了插入int数据，进行类型转换-Integer.parseInt(field1)
			else {
				sql="insert into Histrjn( b,PersonID) values("+Integer.parseInt(field1)+ ",'"+field2+"','"+field3+"','"+field4+"',"+Integer.parseInt(field5)+",'"+field6+"',"+Integer.parseInt(field7)+")";
				System.out.println(sql);	
				//打开数据库连接
				try {
					DB.openConn();
					//执行sql语句
					DB.executeUpdate(sql);
					//提示信息
					JOptionPane.showMessageDialog(null, "你成功添加一条新的纪录");
				} catch (Exception e) {
					// TODO: handle exception
					//出现异常 ，给出提示
					System.out.println(e);
					JOptionPane.showMessageDialog(null, "保存失败 ","错误！", JOptionPane.ERROR_MESSAGE);
				}
					//关闭语句对象和链接对象
					finally{
						DB.closeStmt();
						DB.closeConn();
					}
				}
		}
			/*
			 * 根据JourNo
			 * ，返回人员信息各列值组成的字符数组
			 */
			public String[] search(String f1) {
				Database DB=new Database();
				this.field1=f1;
				//创建字符串数组 用于记录查询的数据
				String[] s =new String[6];
				sql="select * from Histrjn where JourNo="+field1;
				try{
					DB.openConn();//连接数据库
					//执行查询，查询结果付给rs，rs为结果集
					rs=DB.executeQuery(sql);
					//如果rs.next为true
					if (rs.next()) {
						//获取指定的值
						//说明：PersonID'DeptId salary均不是String类型
						//但在此简化处理，把取出值看作字符串，赋值给字符数组元素
						//方便统一待会返回值
						s[0]=rs.getString("JourNo");
						s[1]=rs.getString("FromAcc");
						s[2]=rs.getString("OldInfo");
						s[3]=rs.getString("NewInfo");
						s[4]=rs.getString("ChgTime");
						s[5]=rs.getString("RegDate");
						s[6]=rs.getString("PersonID");
					}else {
						s=null;
					}
				}catch(Exception e){
					
				}finally {
						DB.closeStmt();
						DB.closeConn();
					}
				return s;
				}
			/*
			 * 根据PersonID
			 * ，返回人员信息各列值组成的字符数组
			 */
			public String[] searchPI(String f7) {
				Database DB=new Database();
				this.field1=f7;
				//创建字符串数组 用于记录查询的数据
				String[] s =new String[6];
				sql="select * from Histrjn where PersonID="+field7;
				try{
					DB.openConn();//连接数据库
					//执行查询，查询结果付给rs，rs为结果集
					rs=DB.executeQuery(sql);
					//如果rs.next为true
					if (rs.next()) {
						//获取指定的值
						//说明：PersonID'DeptId salary均不是String类型
						//但在此简化处理，把取出值看作字符串，赋值给字符数组元素
						//方便统一待会返回值
						s[0]=rs.getString("JourNo");
						s[1]=rs.getString("FromAcc");
						s[2]=rs.getString("OldInfo");
						s[3]=rs.getString("NewInfo");
						s[4]=rs.getString("ChgTime");
						s[5]=rs.getString("RegDate");
						s[6]=rs.getString("PersonID");
					}else {
						s=null;
					}
				}catch(Exception e){
					
				}finally {
						DB.closeStmt();
						DB.closeConn();
					}
				return s;
				}
			}
		

&lt;/pre></description></item><item><title>人事管理系统——Dept表增删改查操作类</title><link>https://pangyd.com/post/38-dept/</link><pubDate>Mon, 07 Aug 2017 13:36:21 +0800</pubDate><guid>https://pangyd.com/post/38-dept/</guid><description>&lt;pre lay-lang="Java" class="layui-code" skin="notepad">package com.jnzyjsxy.common;

import java.sql.ResultSet;

import javax.swing.JOptionPane;

public class DeptBean {
	//定义字符串用于存储sql字符串
	String sql;
	//结果集类
	ResultSet rs=null;
	//声明字符串变量 存储从操作界面传过来的人员信息
	String field1;
	String field2;
	String field3;
	//添加信息
	public void add(String f1,String f2,String f3) {
		//创建数据库对象 执行数据库里面的方法 链接数据库 执行sql语句
		Database DB=new Database();
		//将从添加界面传过来的值 付给成员变量
		this.field1=f1;
		this.field2=f2;
		this.field3=f3;
		if (field2==null || field2.equals("")) {
			JOptionPane.showMessageDialog(null, "请输入人员所在一级部门", "错误", JOptionPane.ERROR_MESSAGE);
			return;
		}
		else if (field3==null||field3.equals("")) {
			JOptionPane.showMessageDialog(null,"请输入人员所在二级部门","错误",
					JOptionPane.ERROR_MESSAGE);
			return;
		}
		//构建插入字符串
				//构建sql字符串时，注意字符型，两侧用单引号做定界符，int,float不用定界符
				//传递过来的数据是字符型， 
				//为了插入int数据，进行类型转换-Integer.parseInt(field1) 
				//在此PersonID，DeptID均为int类型，Sqlary为float类型，与书上不同 
				else {
					sql="insert into Dept(DeptID,B_Dept,S_Dept) values("+Integer.parseInt(field1)+ ",'"+field2+"','"+field3+"')";
					System.out.println(sql);	
					//打开数据库连接
					try {
						DB.openConn();
						//执行sql语句
						DB.executeUpdate(sql);
						//提示信息
						JOptionPane.showMessageDialog(null, "你成功添加一条新的纪录");
					} catch (Exception e) {
						// TODO: handle exception
						//出现异常 ，给出提示
						System.out.println(e);
						JOptionPane.showMessageDialog(null, "保存失败 ","错误！", JOptionPane.ERROR_MESSAGE);
					}
						//关闭语句对象和链接对象
						finally{
							DB.closeStmt();
							DB.closeConn();
					}
			}
	}
	/*
	 * 修改设备信息
	 */
	public void modify(String f1,String f2,String f3){
		Database DB=new Database();
		this.field1=f1;
		this.field2=f2;
		this.field3=f3;
		if (field2==null || field2.equals("")) {
			JOptionPane.showMessageDialog(null, "请输入人员所在一级部门", "错误", JOptionPane.ERROR_MESSAGE);
			return;
		}
		else if (field3==null||field3.equals("")) {
			JOptionPane.showMessageDialog(null,"请输入人员所在二级部门","错误",
					JOptionPane.ERROR_MESSAGE);
			return;
		}
		//构建插入字符串
		//构建sql字符串时，注意字符型，两侧用单引号做定界符，int,float不用定界符
		//传递过来的数据是字符型， 
		//为了插入int数据，进行类型转换-Integer.parseInt(field1) 
		//在此PersonID，DeptID均为int类型，Sqlary为float类型，与书上不同 
		else {
			sql="insert into Dept(DeptID,B_Dept,S_Dept) values("+Integer.parseInt(field1)+ ",'"+field2+"','"+field3+"')";
			System.out.println(sql);	
			//打开数据库连接
			try {
				DB.openConn();
				//执行sql语句
				DB.executeUpdate(sql);
				//提示信息
				JOptionPane.showMessageDialog(null, "你成功修改一条新的纪录");
			} catch (Exception e) {
				// TODO: handle exception
				//出现异常 ，给出提示
				System.out.println(e);
				JOptionPane.showMessageDialog(null, "保存失败 ","错误！", JOptionPane.ERROR_MESSAGE);
			}
				//关闭语句对象和链接对象
				finally{
					DB.closeStmt();
					DB.closeConn();
			}
		}
	}
	/*
	 * 删除信息 根据传过来的PersonId 删除信息
	 */
	public void delete(String f1) {
		//创建数据库对象
		Database DB=new Database();
		this.field1=f1;//获取传递过来的参数
		//构建删除人员的字符串
		sql="delete from Dept where DeptID="+Integer.parseInt(field1);
		try {
			DB.openConn();
			DB.executeUpdate(sql);
			System.out.println(sql);
			JOptionPane.showMessageDialog(null, "成功删除一条新的纪录");	
		} catch (Exception e) {
			// TODO: handle exception
			System.out.println(e);
			JOptionPane.showMessageDialog(null, "删除失败", "错误", JOptionPane.ERROR_MESSAGE);
			
	}
		finally{
			DB.closeStmt();
			DB.closeConn();
		}
	}
	/*
	 * 从Dept表查询所有人员信息，DeptID列显示部门名称 
	 */
	public String[][] searchAll() {
		Database DB=new Database();
		//定义二维数组
		String[][] sn=null;
		int row=0;//行数
		int i=0;//循环变量
		//查询sql字符串
		sql="select * from Dept order by DeptID";
		try {
			DB.openConn();
			rs=DB.executeQuery(sql);
				if (rs.last()) {
					row=rs.getRow();//获取结果集rs中记录数，即行数
				}
				//如果row==0说明rs没有记录 既没有查到符号条件的记录
				if (row==0) {
					//初始化二维数组1行6列 每个元素为空白字符
					sn=new String[1][2];
					sn[0][0]="";
					sn[0][1]="";
					sn[0][2]="";
				}
				//否则rs不等于0
				else {
					//根据行数row 初始化二维数组sn
					sn=new String[row][2];
					//让rs指到第一条数据
					rs.first();
					//将指针移动到上一行 由于上一条语句记录指针到第一条数据
					//执行完这条语句后 记录指针移动的rs的头部分
					//执行该条语句的作用是保障所有的记录都能满足rs.next()条件
					rs.previous();
					while (rs.next()) {
						sn[i][0]=rs.getString("DeptID");
						sn[i][1]=rs.getString("B_Dept");
						sn[i][2]=rs.getString("S_Dept");
						i++;			
					} 
				}
		}catch (Exception e) {
			// TODO: handle exception
		}finally {
			DB.closeStmt();
			DB.closeConn();
		}
		return sn;	
	}
	/*
	 * 获得新的Dept值
	 */
	public int getId() {
		Database DB=new Database();
		int ID=1;
		//查询sql，从Person表获取PersonID列的最大值
		sql="select max(DeptID) from Dept";
		try {
			DB.openConn();
			rs=DB.executeQuery(sql);
			if (rs.next()) {
				ID=rs.getInt(1)+1;
			}else {
				ID=1;
			}
		} catch (Exception e) {
			// TODO: handle exception
			
		}
		finally {
			DB.closeStmt();
			DB.closeConn();
		}
		return ID;
	}
	/*
	 * 根据DeptID查询人员信息，返回人员信息各列值组成的字符数组
	 */
	public String[] search(String f1) {
		Database DB=new Database();
		this.field1=f1;
		//创建字符串数组 用于记录查询的数据
		String[] s =new String[10];
		sql="select * from Dept where DeptID="+field1;
		try{
			DB.openConn();//连接数据库
			//执行查询，查询结果付给rs，rs为结果集
			rs=DB.executeQuery(sql);
			//如果rs.next为true
			if (rs.next()) {
				//获取指定的值
				//说明：PersonID'DeptId salary均不是String类型
				//但在此简化处理，把取出值看作字符串，赋值给字符数组元素
				//方便统一待会返回值
				s[0]=rs.getString("DeptID");
				s[1]=rs.getString("B_Dept");
				s[2]=rs.getString("S_Dept");
			}else {
				s=null;
				}
			}catch(Exception e){
				
			}finally {
					DB.closeStmt();
					DB.closeConn();
				}
			return s;
	}
	
	/*
	 * 根据传递过来的ID 返回一级部门—耳机部门
	 */
	public String getDepstr(String string) {
		// TODO Auto-generated method stub
		Database DB=new Database();
		this.field1=string;
		//创建字符串数组 用于记录查询的数据
		String s = null;
		sql="select * from Dept where DeptID="+field1;
		System.out.println(sql);
		try{
			DB.openConn();//连接数据库
			//执行查询，查询结果付给rs，rs为结果集
			rs=DB.executeQuery(sql);
			//如果rs.next为true
			if (rs.next()) {
				//获取指定的值
				//说明：PersonID'DeptId salary均不是String类型
				//但在此简化处理，把取出值看作字符串，赋值给字符数组元素
				//方便统一待会返回值
				s=rs.getString("B_Dept")+"-"+rs.getString("S_Dept"); 	
			}else {
				s=null;
				}
			}catch(Exception e){
				
			}finally {
					DB.closeStmt();
					DB.closeConn();
				}
			return s;
	}
	
}
&lt;/pre></description></item><item><title>”无法解析类型 这是简介引用的类文件要求 从必需的 .class 文件间接引用了“——解决方法</title><link>https://pangyd.com/post/37-class/</link><pubDate>Sun, 06 Aug 2017 19:30:39 +0800</pubDate><guid>https://pangyd.com/post/37-class/</guid><description>&lt;p>&lt;b>百度翻译：&lt;/b>&lt;/p>&lt;p>在线程的“主”java.lang.error例外：解决编制问题： &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 类型javax.swing.jcomponent不能解决。这是间接引用的类文件的要求。 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p>&lt;p>该方法在类型数据库executeupdate()不适用于参数（字符串） &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 方法showmessagedialog（组件对象）在型JOptionPane不适用于参数（null，String，int） &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p>&lt;p>COM。jnzyjsxy。常见。personbean。&amp;lt;初始化&amp;gt;（personbean。java：53） &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; COM。jnzyjsxy。测试。文字。主要（文本。java：13）&amp;nbsp;&lt;/p>&lt;p>&lt;b>这个编译错误有几个原因：&lt;/b>&lt;/p>&lt;p>1、jdk版本问题&lt;/p>&lt;p>要是报错是某些java包里的东西那就可以肯定是jdk版本的问题，&lt;/p>&lt;p>比如无法解析类型java.lang.Object，无法解析类型java.lang.CharSequence.&lt;/p>&lt;p>解决方法：换jdk版本或者重装jdk&lt;/p>&lt;p>2、maven依赖的jar包有问题&lt;/p>&lt;p>当maven项目引用jar包的时候，有些jar包会失效，导致这个问题。&lt;/p>&lt;p>解决方法：把maven本地库jar包删除重新下载，或者删除后换个仓库下载。&lt;/p></description></item><item><title>人事管理系统——Person表增删改查操作类</title><link>https://pangyd.com/post/36-person/</link><pubDate>Sun, 06 Aug 2017 19:27:53 +0800</pubDate><guid>https://pangyd.com/post/36-person/</guid><description>&lt;pre lay-lang="Java" class="layui-code" skin="notepad">package com.jnzyjsxy.common;

import java.sql.ResultSet;

import javax.sound.midi.VoiceStatus;
import javax.swing.JOptionPane;

import org.omg.CORBA.PUBLIC_MEMBER;
/*
 * 有关人员信息数据库操作的类
 */
public class PersonBean {
	//定义字符串用于存储sql字符串
	String sql;
	//结果集类
	ResultSet rs=null;
	//声明字符串变量 存储从操作界面传过来的人员信息
	String field1;
	String field2;
	String field3;
	String field4;
	String field5;
	String field6;
	String field7;
	String field8;
	String field9;
	String field10;
	
	String colname;//列名
	String colvalue1;//列值1
	String colvalue2;//列值2
	
	/*
	 * 添加信息
	 */
	public void add(String f1,String f2,String f3,String f4,String f5,
			String f6,String f7,String f8,String f9,String f10) {
		//创建数据库对象 执行数据库里面的方法 链接数据库 执行sql语句
		Database DB=new Database();
		//将从添加界面传过来的值 付给成员变量
		this.field1=f1;
		this.field2=f2;
		this.field3=f3;
		this.field4=f4;
		this.field5=f5;
		this.field6=f6;
		this.field7=f7;
		this.field8=f8;
		this.field9=f9;
		this.field10=f10;
		//判断穿过来的值是否为空 如果为空就显示提示语句
		if (field2==null || field2.equals("")) {
			JOptionPane.showMessageDialog(null, "请输入人员姓名", "错误", JOptionPane.ERROR_MESSAGE);
			return;
		}
		else if (field3==null||field3.equals("")) {
			JOptionPane.showMessageDialog(null,"请输入性别","错误",
					JOptionPane.ERROR_MESSAGE);
			return;
		}
		else if (field4==null||field4.equals("")) {
			JOptionPane.showMessageDialog(null,"请输入出生年月","错误",
					JOptionPane.ERROR_MESSAGE);
			return;
		}
		else if (field5==null||field5.equals("")) {
			JOptionPane.showMessageDialog(null,"请输入民族","错误",
					JOptionPane.ERROR_MESSAGE);
			return;
		}
		else if (field6==null||field6.equals("")) {
			JOptionPane.showMessageDialog(null,"请输入地址","错误",
					JOptionPane.ERROR_MESSAGE);
			return;
		}
		else if (field7==null||field7.equals("")) {
			JOptionPane.showMessageDialog(null,"请输入部门","错误",
					JOptionPane.ERROR_MESSAGE);
			return;
		}
		else if (field8==null||field8.equals("")) {
			JOptionPane.showMessageDialog(null,"请输入薪酬","错误",
					JOptionPane.ERROR_MESSAGE);
			return;
		}
		//构建插入字符串
		//构建sql字符串时，注意字符型，两侧用单引号做定界符，int,float不用定界符
		//传递过来的数据是字符型， 
		//为了插入int数据，进行类型转换-Integer.parseInt(field1) 
		//在此PersonID，DeptID均为int类型，Sqlary为float类型，与书上不同 
		else {
			sql="insert into Person(PersonID,Name,Sex,Birth,Nat,Address,DeptID,Salary,Assess,Other) values("+Integer.parseInt(field1)+ ",'"+field2+"','"+field3+"','"+field4+"','"+field5+"','"+field6+"',"+Integer.parseInt(field7)+","+Float.parseFloat(field8)+",'"+field9+"','"+field10+"')";
			System.out.println(sql);	
			//打开数据库连接
			try {
				DB.openConn();
				//执行sql语句
				DB.executeUpdate(sql);
				//提示信息
				JOptionPane.showMessageDialog(null, "你成功添加一条新的纪录");
			} catch (Exception e) {
				// TODO: handle exception
				//出现异常 ，给出提示
				System.out.println(e);
				JOptionPane.showMessageDialog(null, "保存失败 ","错误！", JOptionPane.ERROR_MESSAGE);
			}
				//关闭语句对象和链接对象
				finally{
					DB.closeStmt();
					DB.closeConn();
				}
			}
		}
		/*
		 * 修改设备信息
		 */
	public void modify(String f1,String f2,String f3,String f4,String f5,
			String f6,String f7,String f8,String f9,String f10) {
		Database DB=new Database();
		this.field1=f1;
		this.field2=f2;
		this.field3=f3;
		this.field4=f4;
		this.field5=f5;
		this.field6=f6;
		this.field7=f7;
		this.field8=f8;
		this.field9=f9;
		this.field10=f10;
		if (field2==null || field2.equals("")) {
			JOptionPane.showMessageDialog(null, "请输入人员姓名", "错误", JOptionPane.ERROR_MESSAGE);
			return;
		}
		else if (field3==null||field3.equals("")) {
			JOptionPane.showMessageDialog(null,"请输入性别","错误",
					JOptionPane.ERROR_MESSAGE);
			return;
		}
		else if (field4==null||field4.equals("")) {
			JOptionPane.showMessageDialog(null,"请输入出生年月","错误",
					JOptionPane.ERROR_MESSAGE);
			return;
		}
		else if (field5==null||field5.equals("")) {
			JOptionPane.showMessageDialog(null,"请输入民族","错误",
					JOptionPane.ERROR_MESSAGE);
			return;
		}
		else if (field6==null||field6.equals("")) {
			JOptionPane.showMessageDialog(null,"请输入地址","错误",
					JOptionPane.ERROR_MESSAGE);
			return;
		}
		else if (field7==null||field7.equals("")) {
			JOptionPane.showMessageDialog(null,"请输入部门","错误",
					JOptionPane.ERROR_MESSAGE);
			return;
		}
		else if (field8==null||field8.equals("")) {
			JOptionPane.showMessageDialog(null,"请输入薪酬","错误",
					JOptionPane.ERROR_MESSAGE);
			return;
		}
		//构建插入字符串
		//构建sql字符串时，注意字符型，两侧用单引号做定界符，int,float不用定界符
		//传递过来的数据是字符型， 
		//为了插入int数据，进行类型转换-Integer.parseInt(field1) 
		//在此PersonID，DeptID均为int类型，Sqlary为float类型，与书上不同 
		else {
			sql="updata into Person(PersonID,Name,Sex,Birth,Nat,Address,DeptID,Salary,Assess,Other) values("+Integer.parseInt(field1)+ ",'"+field2+"','"+field3+"','"+field4+"','"+field5+"','"+field6+"',"+Integer.parseInt(field7)+","+Float.parseFloat(field8)+",'"+field9+"','"+field10+"')";
			System.out.println(sql);	
			//打开数据库连接
			try {
				DB.openConn();
				//执行sql语句
				DB.executeUpdate(sql);
				//提示信息
				JOptionPane.showMessageDialog(null, "你成功修改一条新的纪录！");
			} catch (Exception e) {
				// TODO: handle exception
				//出现异常 ，给出提示
				System.out.println(e);
				JOptionPane.showMessageDialog(null, "保存失败 ","错误！", JOptionPane.ERROR_MESSAGE);
			}
			finally{
				DB.closeStmt();
				DB.closeConn();
			}
	}

}
	/*
	 * 删除信息 根据传过来的PersonId 删除信息
	 */
	public void delete(String f1) {
		//创建数据库对象
		Database DB=new Database();
		this.field1=f1;//获取传递过来的参数
		//构建删除人员的字符串
		sql="delete from Person where PersonID="+Integer.parseInt(field1);
		try {
			DB.openConn();
			DB.executeUpdate(sql);
			System.out.println(sql);
			JOptionPane.showMessageDialog(null, "成功删除一条新的纪录");	
		} catch (Exception e) {
			// TODO: handle exception
			System.out.println(e);
			JOptionPane.showMessageDialog(null, "删除失败", "错误", JOptionPane.ERROR_MESSAGE);
			
	}
		finally{
			DB.closeStmt();
			DB.closeConn();
		}
}
	/*
	 * 根据PersonID查询人员信息，返回人员信息各列值组成的字符数组
	 */
	public String[] search(String f1) {
		Database DB=new Database();
		this.field1=f1;
		//创建字符串数组 用于记录查询的数据
		String[] s =new String[10];
		sql="select * from Person where PersonID="+field1;
		try{
			DB.openConn();//连接数据库
			//执行查询，查询结果付给rs，rs为结果集
			rs=DB.executeQuery(sql);
			//如果rs.next为true
			if (rs.next()) {
				//获取指定的值
				//说明：PersonID'DeptId salary均不是String类型
				//但在此简化处理，把取出值看作字符串，赋值给字符数组元素
				//方便统一待会返回值
				s[0]=rs.getString("PersonID");
				s[1]=rs.getString("Name");
				s[2]=rs.getString("Sex");
				s[3]=rs.getString("Birth");
				s[4]=rs.getString("Nat");
				s[5]=rs.getString("Address");
				s[6]=rs.getString("DeptID");
				s[7]=rs.getString("Salary");
				s[8]=rs.getString("Assess");
				s[9]=rs.getString("Other");
			}else {
				s=null;
			}
		}catch(Exception e){
			
		}finally {
				DB.closeStmt();
				DB.closeConn();
			}
		return s;
		}
		/*
		 * 人员信息综合查询
		 * 从PersonID和Dept表查询所有Where DeptID=Person.DeptID部门编号相等的记录
		 */
	public String[][] searchAllForNode() {
		//初始化数据库
		Database DB=new Database();
		//创建二维数组 存储查找到的符号条件记录的咯列值
		//由于符合条件的记录可能有多行，所以需要二维数组
		String[][] sn =null;
		int row=0;//存储行数
		int i=0;//循环变量
		//构建联合查询语句 查询条件where DeptID=Person.DeptID
		//从Person，Dept表查询Where Dept.DeptID=Person.DeptID 条件的指定字段
		sql="select PersonID,Name,Sex,Dept.DeptID as DeptID,B_Dept,S_Dept, Salary,Assess from Dept,Person where Dept.DeptID=Person.DeptID order by PersonID"; 
		try {
			DB.openConn();
			// TODO: handle exception
			//执行查询
			rs=DB.executeQuery(sql);
			//rs.last()--将记录指针移动到最后记录上，该方法类型为boolean
			//如果指针位于有效位,则返回true;如果结果集中不存在任何行,则返回false
			//即如果rs中有记录
			if (rs.last()) {
				row=rs.getRow();//获取结果集rs中记录数，即行数
			}
			//如果row==0说明rs没有记录 既没有查到符号条件的记录
			if (row==0) {
				//初始化二维数组1行6列 每个元素为空白字符
				sn=new String[1][6];
				sn[0][0]="";
				sn[0][1]="";
				sn[0][2]="";
				sn[0][3]="";
				sn[0][4]="";
				sn[0][5]="";
			}
			//否则rs不等于0
			else {
				//根据行数row 初始化二维数组sn
				sn=new String[row][6];
				//让rs指到第一条数据
				rs.first();
				//将指针移动到上一行 由于上一条语句记录指针到第一条数据
				//执行完这条语句后 记录指针移动的rs的头部分
				//执行该条语句的作用是保障所有的记录都能满足rs.next()条件
				rs.previous();
				//结果集下移一条数据 返回true 执行循环
				//如果没有执行re.previons()语句 在执行rs.next（），第一天记录就略过了。
				while (rs.next()) {
					sn[i][0]=rs.getString("PersonID");
					sn[i][1]=rs.getString("Name");
					sn[i][2]=rs.getString("Sex");
					//一级部门-二级部门，存储到sn[i][3]元素中
					sn[i][3]=rs.getString("B_Dept")+"-"+rs.getString("s_Dept");
					sn[i][4]=rs.getString("Salary");
					sn[i][5]=rs.getString("Assess");
					i++;
				}
				
			}
		}catch (Exception e) {

		}finally{
			DB.closeStmt();
			DB.closeConn();
		}
		return sn;
	}
	/*
	 * 修改Person表中 指定用户的部门信息，即修改Person表中的DeptID字段值
	 */
	public void updateDept(String f1,String f8) {
		Database DB=new Database();
		this.field1=f1;//PersonID
		this.field8=f8;//salary 薪资字段
		sql="update Person set Salary =" +Float.parseFloat(field8)+" where PersonID ="+Integer.parseInt(field1);
		try {
			DB.openConn();
			DB.executeUpdate(sql);
			JOptionPane.showMessageDialog(null, "劳资更改成功");
			
		} catch (Exception e) {
			// TODO: handle exception
			System.out.println(e);
			JOptionPane.showMessageDialog(null, "更新失败", "失败",JOptionPane.ERROR_MESSAGE);
		}
	}
	/*
	 * 修改Person表中指定考核信息 即修改Person表中Assess字段值
	 */
	public void updateAssess(String f1,String f9) {
	Database DB=new Database();
	this.field1=f1;
	this.field9=f9;//考核字段
	sql="update Person set Assess = '"+field9 +"' where PersonID ="+Integer.parseInt(field1);
	try{
		DB.openConn();
		DB.executeUpdate(sql);
		JOptionPane.showMessageDialog(null, "人员考核成功");
	}catch(Exception e){
		System.out.println(e);
		JOptionPane.showMessageDialog(null, "更新失败", "失败",
				JOptionPane.ERROR_MESSAGE);
	}
	}

		

	/*
	 * 从Person表查询所有的人员信息 DeptID列显示部门名称
	 */
	public String[][] searchAll() {
		Database DB=new Database();
		//定义二维数组
		String[][] sn=null;
		int row=0;//行数
		int i=0;//循环变量
		//查询sql字符串
		sql="select * from Person order by PersonID";
		try {
			DB.openConn();
			rs=DB.executeQuery(sql);
				if (rs.last()) {
					row=rs.getRow();//获取结果集rs中记录数，即行数
				}
				//如果row==0说明rs没有记录 既没有查到符号条件的记录
				if (row==0) {
					//初始化二维数组1行6列 每个元素为空白字符
					sn=new String[1][6];
					sn[0][0]="";
					sn[0][1]="";
					sn[0][2]="";
					sn[0][3]="";
					sn[0][4]="";
					sn[0][5]="";
				}
				//否则rs不等于0
				else {
					//根据行数row 初始化二维数组sn
					sn=new String[row][6];
					//让rs指到第一条数据
					rs.first();
					//将指针移动到上一行 由于上一条语句记录指针到第一条数据
					//执行完这条语句后 记录指针移动的rs的头部分
					//执行该条语句的作用是保障所有的记录都能满足rs.next()条件
					rs.previous();
					while (rs.next()) {
						sn[i][0]=rs.getString("PersonID");
						sn[i][1]=rs.getString("Name");
						sn[i][2]=rs.getString("Birth");
						sn[i][3]=rs.getString("Nat");
						sn[i][4]=rs.getString("Address");
						//创建部门操作类DeptBean的对象
						DeptBean dBean=new DeptBean();
						sn[i][5]=dBean.getDepstr(rs.getString("DeptID"));
						i++;			
					} 
				}
		}catch (Exception e) {
			// TODO: handle exception
		}finally {
			DB.closeStmt();
			DB.closeConn();
		}
		return sn;	
	}
	/*
	 * 获得新的Person值
	 */
	public int getId() {
		Database DB=new Database();
		int ID=1;
		//查询sql，从Person表获取PersonID列的最大值
		sql="select max(PersonID) from Person";
		try {
			DB.openConn();
			rs=DB.executeQuery(sql);
			if (rs.next()) {
				ID=rs.getInt(1)+1;
			}else {
				ID=1;
			}
		} catch (Exception e) {
			// TODO: handle exception
			
		}
		finally {
			DB.closeStmt();
			DB.closeConn();
		}
		return ID;
	}
	/*
	 * 获得DeptID
	 */
	public String getDeptId(String f1) {
		Database DB=new Database();
		//根据传递过来的PersonID 即根据员工编号，查DeptID
		sql="select DeptID from Person where PersonID = "+f1;
		String deptid=null;
		try {
			DB.openConn();
			rs=DB.executeQuery(sql);
			if (rs.next()) {
				deptid=rs.getString("DeptID");
			}else {
				deptid="";
			}
		} catch (Exception e) {
			// TODO: handle exception
		}finally {
			DB.closeStmt();
			DB.closeConn();
		}
		return deptid;
	} 
	/*
	 * 根据PersonID查找员工姓名
	 */
	public String getName(String f1) {
		Database DB=new Database();
		sql="select Name from Person where PersonID ="+f1;
		String name=null;
		try {
			DB.openConn();
			rs=DB.executeQuery(sql);
			if (rs.next()) {
				name =rs.getString("Name");
			}
			else {
				name="";
				
			}
		} catch (Exception e) {
			// TODO: handle exception
		}finally {
			DB.closeStmt();
			DB.closeConn();
		}
		return name;
	}
	/*
	 * 从perSon表中查找所有PersonID Name字段 存储在s数组中 返回
	 */
	public String[] getAllId() {
		String[] s=null;
		int row=0;
		int i=0;
		Database DB=new Database();
		sql="select PersonID,Name from Person order by PersonID";
		try {
			DB.openConn();
			rs=DB.executeQuery(sql);
			if (rs.last()) {
				row=rs.getRow();
			}
			if (row==0) {
				s=null;
			}else {
				s=new String[row];
				rs.first();
				rs.previous();
				while (rs.next()) {
				s[i]=rs.getString(1)+"-"+rs.getShort(2);
				i++;
					
				}
			}
		} catch (Exception e) {
			// TODO: handle exception
			System.out.println(e);
		}finally {
			DB.closeStmt();
			DB.closeConn();
		}
		return s;
	}
	}
&lt;/pre></description></item><item><title>干货 | 机器学习算法大总结(ML岗面试常考)</title><link>https://pangyd.com/post/35-ml/</link><pubDate>Sat, 05 Aug 2017 17:16:10 +0800</pubDate><guid>https://pangyd.com/post/35-ml/</guid><description>&lt;p style="text-align: justify">&amp;nbsp;找工作时（IT行业），除了常见的软件开发以外，机器学习岗位也可以当作是一个选择，不少计算机方向的研究生都会接触这个，如果你的研究方向是机器学习/数据挖掘之类，且又对其非常感兴趣的话，可以考虑考虑该岗位，毕竟在机器智能没达到人类水平之前，机器学习可以作为一种重要手段，而随着科技的不断发展，相信这方面的人才需求也会越来越大。&lt;/p>&lt;p>&lt;span style="text-align: justify">　　&lt;/span>&lt;br>&lt;/p>&lt;p style="text-align: justify">下面是在找机器学习岗位工作时，总结的常见机器学习算法（主要是一些常规分类器）大概流程和主要思想，希望对大家找机器学习岗位时有点帮助。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p style="text-align: justify">实际上在面试过程中，懂这些算法的基本思想和大概流程是远远不够的，那些面试官往往问的都是一些公司内部业务中的课题，往往要求你不仅要懂得这些算法的理论过程，而且要非常熟悉怎样使用它，什么场合用它，算法的优缺点，以及调参经验等等。说白了，就是既要会点理论，也要会点应用，既要有点深度，也要有点广度，否则运气不好的话很容易就被刷掉，因为每个面试官爱好不同。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;strong style="text-align: justify">&lt;span>朴素贝叶斯：&lt;/span>&lt;/strong>&lt;br>&lt;/p>&lt;p style="text-align: justify">　　有以下几个地方需要注意：&lt;/p>&lt;p style="text-align: justify">　　1. 如果给出的特征向量长度可能不同，这是需要归一化为通长度的向量（这里以文本分类为例），比如说是句子单词的话，则长度为整个词汇量的长度，对应位置是该单词出现的次数。&lt;/p>&lt;p style="text-align: justify">　　2. 计算公式如下：&lt;/p>&lt;p style="text-align: justify">　　&lt;img class="" data-ratio="0.3229571984435798" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-type="png" data-w="257" height="69" width="214" _width="auto" src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-fail="0">&lt;/p>&lt;p style="text-align: justify">　　其中一项条件概率可以通过朴素贝叶斯条件独立展开。要注意一点就是&amp;nbsp;&lt;img class="" data-ratio="0.3764705882352941" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-type="png" data-w="85" _width="auto" src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-fail="0">的计算方法，而由朴素贝叶斯的前提假设可知，&lt;img class="" data-ratio="0.13725490196078433" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-type="png" data-w="204" _width="auto" src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-fail="0">&amp;nbsp;=&lt;img class="" data-ratio="0.0812807881773399" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-type="png" data-w="406" _width="auto" src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-fail="0">&amp;nbsp;，因此一般有两种，一种是在类别为ci的那些样本集中，找到wj出现次数的总和，然后除以该样本的总和；第二种方法是类别为ci的那些样本集中，找到wj出现次数的总和，然后除以该样本中所有特征出现次数的总和。&lt;/p>&lt;p style="text-align: justify">　　3. 如果&amp;nbsp;&lt;img class="" data-ratio="0.3764705882352941" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-type="png" data-w="85" _width="auto" src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-fail="0">中的某一项为0，则其联合概率的乘积也可能为0，即2中公式的分子为0，为了避免这种现象出现，一般情况下会将这一项初始化为1，当然为了保证概率相等，分母应对应初始化为2（这里因为是2类，所以加2，如果是k类就需要加k，术语上叫做laplace光滑, 分母加k的原因是使之满足全概率公式）。&lt;/p>&lt;p style="text-align: justify">　　&lt;span>&lt;em>&lt;strong>朴素贝叶斯的优点：&lt;/strong>&lt;/em>&lt;/span>&lt;/p>&lt;p style="text-align: justify">　　对小规模的数据表现很好，适合多分类任务，适合增量式训练。&lt;/p>&lt;p style="text-align: justify">&lt;span>　　&lt;strong>&lt;em>缺点&lt;/em>：&lt;/strong>&lt;/span>&lt;/p></description></item><item><title>“努力一暑假开学当学霸” 学生的暑假是怎样被“玩”坏的？</title><link>https://pangyd.com/post/34/</link><pubDate>Sat, 05 Aug 2017 17:11:15 +0800</pubDate><guid>https://pangyd.com/post/34/</guid><description>&lt;p class="" style="text-align: justify">（原标题：“努力一暑假开学当学霸” 学生的暑假是怎样被“玩”坏的？）&lt;/p>&lt;ul class="list-paddingleft-2">&lt;li>&lt;p style="text-align: center">&lt;img data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" class="" data-ratio="0.7269230769230769" data-w="260" data-type="jpeg" src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-fail="0">&lt;/p>&lt;p style="text-align: center">&lt;br>“游”大于“学”，出境游学成了旅游项目一个昂贵的“变体”。现在旅行团加个“游学”的名头就能售价暴涨，但实际上只是普通旅游。&lt;br>&lt;br>&lt;/p>&lt;/li>&lt;/ul>&lt;p>暑假本应是孩子们“狂欢”的时候，但现在却被各种培训班淹没，甚至有培训班打出“努力一暑假，开学当学霸” 的口号，孩子不能放松，家长也并不轻松，有些培训班要求家长必须陪读以便每天回家能辅导孩子复习。&lt;br>　　与此相对的，有些家长选择把孩子送出国去游学，可游学也并不是一件省心的事儿，日前有媒体爆出，有不少旅行社就打出游学的幌子而只是出国一趟只游不学而已。&lt;br>　　很多家长是报着不能让孩子输在起跑线上的心态将孩子们的暑假安排得满满当当，家长也应换个角度想想，如果是自己小时候的暑假，又可会愿意被这么安排？孩子们的暑假，究竟该怎么过？&lt;/p>&lt;p style="text-align: center">&lt;strong>才上幼儿园 孩子的作业已经做不完&lt;/strong>&lt;/p>&lt;p>嘟嘟今年5岁半，在妈妈嘴里就是“马上就要进入幼小衔接的关键时期”，嘟嘟妈这个暑假给孩子报的班，排满了七八两个月。打开嘟嘟妈的手机，日历上赤橙黄绿青蓝紫一片彩虹色，用不同颜色标记的培训班竟然多达9个。&lt;br>　　看到那张让人眼花缭乱的日程表，有被吓到的感觉，但是嘟嘟妈非常肯定地表示：“我们孩子报得不算多的。”&lt;br>　　据了解，虽然很多培训班是短期的，日程有错开，不过，5岁半的嘟嘟最忙的一天，从上午到晚上排了4个班——早上是美术课，接着钢琴课，下午是一对一游泳课，晚上是英语班。&lt;br>　　这么紧凑的日子，嘟嘟需要两代人接送。白天是爷爷送，晚上等妈妈下班了就妈妈送。但作为医生，嘟嘟妈有时候还会轮到夜班，再加上各种学习和出差，她自己的日程表会叠加一倍的量，“精力顾不过来”。&lt;br>　　才幼儿园的嘟嘟已经要应付一大堆培训班作业了。英语班，暑期是集中训练15天，每天都要上课。英语课的课后作业，是培训机构自己开发的App程序，每周要完成 90个选择题，这些作业还是收费的，一元3个选择题。虽然作业很繁重，但嘟嘟妈承认做作业比单纯听课效果要好。&lt;br>　　但相比花样繁多的培训班，上课的内容还真是有点“水”。&lt;br>　　嘟嘟的妈妈说，一个《渔夫和金鱼》 的故事，被 3个培训班的老师用来教学。&lt;br>　　英语课上，这个故事是用英文讲的，回家以后要在App上做选择题：渔夫的妻子提了什么要求？选项还特别长。&lt;br>　　儿童剧班里，老师也表演了《渔夫和金鱼》的故事。&lt;br>　　到了乐高夏令营里，又是《渔夫和金鱼》。老师讲完故事，让孩子们用乐高玩具搭出故事场景。&lt;br>　　渔夫和金鱼也是够累的。&lt;br>　　可是，即便如此，也没有阻挡这位80后妈妈给孩子报班。说到为什么要给孩子上儿童剧班，嘟妈妈表示，“我自己感觉开会发言、上台做报告的口才很重要，现在已经很流行戏剧课啦。”她说，朋友的孩子报了据说是冯小刚投资的一个全英文戏剧教学，一次课要 300多元，“这么贵的班，照样被抢完。”&lt;br>　　暑假这两个月，这七七八八的培训班，一共花了嘟妈妈 10000多元，但她表示，她给孩子报的班都不是很贵。&lt;/p>&lt;p style="text-align: center">&lt;strong>“努力一暑假 开学当学霸”&lt;/strong>&lt;/p>&lt;p>辰辰该上三年级了。二年级期末考试，他的数学只得了92分，这让陈明敏挺不满意，“班里有两个学生考了满分，半数学生都在95分以上”。她有些自责，怪自己没早点给孩子报数学辅导班，而暑假正是“弯道超车”的最佳时刻。&lt;br>　　她关注了一个很火的数学辅导班，网站上打出令家长们“心潮澎湃”的口号——“努力一暑假 开学当学霸”。每天上两个半小时，连续上20天为一期，中间只有一天休息，同时老师提出一个硬性要求——家长必须陪读，以便每天回家辅导孩子复习。&lt;br>　　陈明敏的工作挺忙，但她还是咬了咬牙点头答应了。她盘算着只有每天午休自己时间稍微宽松些，决定给孩子报个中午班。&lt;br>　　每天上午 11点半，盛夏日头最毒的时候，她就会打仗似的冲出办公楼开车回家接孩子，并赶在12点前准时坐进教室。在班里，她是最认真的“学生”，老师在前面讲，她在下面记录，每次笔记都密密麻麻记好几页，“比自己上学时可认真多了，不能因为我影响儿子学习啊”。&lt;br>　　除了每天两小时数学课，陈明敏还给儿子报了英语课和游泳课。英语课是周二和周五晚上，每次各1个小时；周末下午是游泳课。&lt;br>　　这样一来，辰辰似乎比没放假时更忙了。他的暑期时间安排表排得满满当当：每天上午必须要完成数学和英语作业；中午上数学课；晚上除了上课，就是复习巩固数学和英语的学习情况。&lt;/p>&lt;p style="text-align: center">&lt;strong>出境游学成了旅游项目昂贵的“变体”&lt;/strong>&lt;/p>&lt;p>李元的儿子只是小学五年级学生，但他班上90%的同学都已经去过不少国家游学。之前李元认为孩子岁数小，不放心让他单独出门，这回看起来等不得了。“假期一结束，孩子们就会在一起讨论谁去的国家好玩，没去游学的同学无形之中被隔离在外，不但在同学面前没有谈资，还有可能被同学瞧不起。”李元说，今年一定要给他儿子报个出国游学项目。&lt;br>　　山东济南的公务员韩春去年给女儿报名参加一个海外游学项目。本来全家人对游学充满了期待，想早早做好准备。&lt;br>　　直到出发前 3天，旅行社才告诉韩春一家集合地点和应带物品，相关信息与游学关联性不大，倒是和平时出国旅行没什么两样。“出去后就发现不对劲。不少学习、交流环节都因为这个那个原因取消，反倒增加了一堆购物环节，就在各个大小商店之间游荡。 学 没游成，光去购物了。”这一次，前后报名费就花去 6万多元，几乎相当于他半年的收入。&lt;/p>&lt;p style="text-align: center">&lt;strong>不要用金钱堆砌孩子的暑假&lt;/strong>&lt;/p>&lt;p>城市里的孩子暑假期间在各类培训班、特长班中忙得不亦乐乎，在培训班里被强化着扼杀想象力、创造力。以提高分数为目标的应试训练，让教育成为了一种“烧钱游戏”。&lt;br>　　“烧钱式教育”背后的家长们，在这场游戏中最终都难以获胜，也不会有最后的赢家。教育是一场长跑，起跑线上的竞争决定不了最后的输赢，什么时候做什么事情，必须符合天性，符合教育规律。&lt;/p>&lt;p>起跑线上的竞争违背教育规律，是典型的拔苗助长，对孩子的长远发展而言，可能也是弊大于利。可怕的是，家长不如此，便不心安。家长之间的互相攀比，互相较劲给孩子报了多少培训班、特长班，再加上校外培训机构的刺激、诱导，被裹在这股洪流之中，人们很容易失去理性，如果不节制，别说3万元，30万也可能撑不起一个暑假。&lt;/p>&lt;p>　　其实，在多位中小学教师和教育专家看来，放假期间，家长给孩子更多的亲子陪伴，比上一些课外班要重要得多。在这期间，家长应是孩子的向导和伙伴，比如可以引导孩子做自己的暑假计划，规定每天的作息、学习时间和休息娱乐时间，并要求孩子严格遵守，培养其规划时间的能力和责任心。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p style="text-align: right">据新华社&lt;br>&lt;/p>&lt;p style="text-align: right">(原标题：“努力一暑假开学当学霸” 学生的暑假是怎样被“玩”坏的？)&lt;/p></description></item><item><title>正确学习Python的姿势</title><link>https://pangyd.com/post/33-python/</link><pubDate>Sat, 05 Aug 2017 17:07:32 +0800</pubDate><guid>https://pangyd.com/post/33-python/</guid><description>&lt;section data-role="outer" label="Powered by 135editor.com">&lt;p>&lt;span>&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 想学Python，刚开始有没有觉得无从下手呢？其实Python的基础知识点，并不多，但是一定要吃透，因为这是为后续核心的学习打下一个良好的基础。俗话说：万丈高楼平地起！&lt;/span>&lt;br>&lt;/p>&lt;/section>&lt;p>&lt;span>&lt;/span>&lt;/p>&lt;p>&lt;img data-s="300,640" data-type="png" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" class="" data-ratio="2.010178117048346" data-w="393" _width="100%" src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-fail="0">&lt;/p>&lt;p>&lt;span>&lt;strong>1、初识庐山真面目-初识Python&lt;/strong>&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;img data-s="300,640" data-type="png" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" class="" data-ratio="0.2401263823064771" data-w="633" _width="100%" src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-fail="0">&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;strong>学习重点：&lt;/strong>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>Python的安装及配置：到官网上下载Python，然后安装。安装后还要进行PATH变量的配置。同时安装2和3的环境变量配置，在cmd命令行中输入Python对安装的结果进行检验。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>&lt;strong>2、再识庐山真面目-简单Python程序（注重对Python的理解）&lt;/strong>&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;img data-s="300,640" data-type="png" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" class="" data-ratio="0.6308411214953271" data-w="642" _width="100%" src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-fail="0">&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;strong>学习重点：&lt;/strong>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>Python基础中的基础，都是重点！&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>不可不知的数据类型（注重编程能力）&lt;/p>&lt;h1>3、不可不知的数据类型（注重编程能力）&lt;/h1>&lt;p>&lt;img data-s="300,640" data-type="png" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" class="" data-ratio="0.7706237424547284" data-w="497" _width="100%" src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-fail="0">&lt;br>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;strong>学习重点：&lt;/strong>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>1、基本数据类型、数据类型的转换&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>2、控制流程、if、if elif、for循环、while循环&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>3、函数&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>面向对象面向君，不负代码不负卿（设计思想）&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;h1>面向对象面向君，不负代码不负卿（设计思想）&lt;/h1>&lt;p>&lt;img data-s="300,640" data-type="png" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" class="" data-ratio="0.7706237424547284" data-w="497" _width="100%" src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-fail="0">&lt;/p></description></item><item><title>JDBC数据库连接代码</title><link>https://pangyd.com/post/32-jdbc/</link><pubDate>Sat, 05 Aug 2017 17:02:45 +0800</pubDate><guid>https://pangyd.com/post/32-jdbc/</guid><description>&lt;p>&lt;/p>&lt;pre lay-lang="Java" class="layui-code" skin="notepad">package com.jnzyjsxy.common;
&lt;p>import java.sql.DriverManager;&lt;/p>
&lt;p>import java.sql.ResultSet;&lt;/p>
&lt;p>import com.mysql.jdbc.Connection;&lt;/p>
&lt;p>import com.mysql.jdbc.Statement;&lt;/p>
&lt;p>/*&lt;/p>
&lt;ul>
&lt;li>数据库连接类&lt;/li>
&lt;/ul>
&lt;p>*/&lt;/p>
&lt;p>public class Database {&lt;/p>
&lt;p>//创建成员变量用于存储数据库连接的字符串或结果&lt;/p>
&lt;p>//statement接口 用于执行静态sql语句 并返回它所生成的结果&lt;/p>
&lt;p>private Statement stmt=null;&lt;/p>
&lt;p>//结果集类&lt;/p>
&lt;p>ResultSet rs=null;&lt;/p>
&lt;p>//链接类&lt;/p>
&lt;p>private Connection conn=null;&lt;/p>
&lt;p>String sql;//存储sql语句&lt;/p>
&lt;p>//mysql数据连接字符串&lt;/p>
&lt;p>//&amp;ldquo;jdbc:mysql://localhost:3306/db_hrms&amp;rdquo;&lt;/p>
&lt;p>//数据库名称db_hrms&lt;/p>
&lt;p>//在数据库名称后，增加&amp;quot;?characterEncoding=GBK&amp;quot;，避免插入记录为乱码&lt;/p>
&lt;p>String strurl=&amp;ldquo;jdbc:mysql://localhost:3306/db_hrms?characterEncoding=GBK&amp;rdquo;;//主机地址&lt;/p>
&lt;p>String username=&amp;ldquo;root&amp;rdquo;;//用户名&lt;/p>
&lt;p>String password=&amp;ldquo;123456&amp;rdquo;;//密码&lt;/p>
&lt;p>//构造方法&lt;/p>
&lt;p>public Database(){&lt;/p>
&lt;p>}&lt;/p>
&lt;p>/*&lt;/p>
&lt;ul>
&lt;li>打开数据库连接&lt;/li>
&lt;/ul>
&lt;p>*/&lt;/p>
&lt;p>public void openConn() {&lt;/p>
&lt;p>try {&lt;/p>
&lt;p>Class.forName(&amp;ldquo;com.mysql.jdbc.Driver&amp;rdquo;);&lt;/p>
&lt;p>//DriverManager.getConnection启动器管理类的连接方法&lt;/p>
&lt;p>//创建数据库连接对象三个参数 初始化conn&lt;/p>
&lt;p>conn=(Connection) DriverManager.getConnection(strurl, username, password);&lt;/p>
&lt;p>System.out.println(&amp;ldquo;数据库连接成功&amp;rdquo;);&lt;/p>
&lt;p>} catch (Exception e) {&lt;/p>
&lt;p>// TODO: handle exception&lt;/p></description></item><item><title>让你的能力，配得上你的愿望</title><link>https://pangyd.com/post/31/</link><pubDate>Fri, 04 Aug 2017 21:16:02 +0800</pubDate><guid>https://pangyd.com/post/31/</guid><description>&lt;p style="text-align: center">&lt;img data-s="300,640" data-type="png" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" class="" data-ratio="0.6636971046770601" data-w="449" src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-fail="0">&lt;/p>&lt;p style="text-align: center">&lt;br>&lt;/p>&lt;section data-author="Wxeditor">&lt;article class="" data-author="Wxeditor">&lt;section style="text-align: center">&lt;section>&lt;br>&lt;/section>&lt;section>&lt;p>1&lt;/p>&lt;/section>&lt;/section>&lt;/article>&lt;/section>&lt;p>&lt;span>&lt;strong style="text-align: justify">&lt;span>　　&lt;/span>&lt;/strong>重温《肖申克的救赎》，里面有句话让我铭记于心：“有些鸟注定是不会被关在笼子里的，因为它们的每一片羽毛都闪耀着自由的光辉。”&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;strong style="text-align: justify">&lt;span>　　&lt;/span>&lt;/strong>我从小就特别羡慕有独到见解，能够在众人面前出口成章又侃侃而谈的人。小学时的我是班级中的“大舌头”，于我而言，语言表达就好似一座巍峨的高山，让人望而却步。每每都快要“咬舌自尽”了，平翘舌音也还是会说错。仍记得，我当时的一个习惯动作就是，只要老师说“我找同学朗诵一下这段课文”，我就会迅速弯下腰，将头藏到书本后面，唯恐老师叫我起来读课文。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;strong style="text-align: justify">&lt;span>　　&lt;/span>&lt;/strong>好好的一篇《春天来了》，被我读成了《村天来了》，引得同学们捧腹大笑。我的脸涨得如充满气的皮球，恨不得能够有一种魔法，可以把刚才难堪的场景统统抹掉。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;strong style="text-align: justify">&lt;span>　　&lt;/span>&lt;/strong>我曾在梦中因不会表达而被人误解，委屈得哭醒。我是多么想能够在大家面前侃侃而谈，收获认可与掌声呀。一心寻求改变的我，开始每天做一些简单的语言练习，坚持了很久。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;strong style="text-align: justify">&lt;span>　　&lt;/span>&lt;/strong>因为我的画画得很好，为班级制作黑板报，设计班旗、班徽让我“火”了一把，很多老师和同学来我们班参观。于是，我们的班主任让我站在讲台上讲一讲我的设计创意，在掌声的鼓励下我说出了这些设计的联想。我站在讲台上，看到他们崇拜与喜爱的目光，竟不自觉地讲了许久。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;strong style="text-align: justify">&lt;span>　　&lt;/span>&lt;/strong>&lt;span>&lt;strong>我们每个人身上都有无限的独特的潜能&lt;/strong>&lt;/span>，如某种才华、技艺、让人开心或者投入的本领等等，&lt;span>&lt;strong>它们就好像是生活道路上赐予我们的礼物，等待着我们努力去探寻。&lt;/strong>&lt;/span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;/p>&lt;section data-author="Wxeditor">&lt;article class="" data-author="Wxeditor">&lt;section style="text-align: center">&lt;section>&lt;img class="" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-ratio="0.5083333333333333" data-w="600" src="https://pangyd.com/uploads/2017/08/44d5041f007d30a9.png">&lt;/section>&lt;section>&lt;p>2&lt;/p>&lt;/section>&lt;/section>&lt;/article>&lt;/section>&lt;p>&lt;span>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;strong style="text-align: justify">&lt;span>　　&lt;/span>&lt;/strong>大学我如愿考入了北京，开学不久就加入了演讲与口才社。说来也巧，正赶上“北京市志远杯高校联合演讲大赛”，怀着对演讲的喜爱，我精心准备了一篇演讲稿，并在初赛200多名选手中，脱颖而出，晋级总决赛。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;strong style="text-align: justify">&lt;span>　　&lt;/span>&lt;/strong>两周后的总决赛上，我人生中第一次面对数百人演讲。我的演讲《用右手撑起一片晴空》，讲述了我自幼失去左臂，却通过努力获得省速滑冠军的故事。当我说到结尾时，现场响起了当天最热烈的掌声。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;strong style="text-align: justify">&lt;span>　　&lt;/span>&lt;/strong>当得知自己获得“2011年北京市志远杯高校联合演讲大赛冠军”时，眼含热泪的我仿佛看到了语言高山后面的大海。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;strong style="text-align: justify">&lt;span>　　&lt;/span>&lt;/strong>那一次的比赛，让我发现原来演讲可以影响很多人，甚至能够改变很多人。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;strong style="text-align: justify">&lt;span>　　&lt;/span>&lt;/strong>为了我小小的&lt;/span>&lt;span>“英雄梦想”，我一有空就在无人的大教室里练习演讲。有一次，一位即将在这个教室上课的理学院的教授听到了我演讲中的一段话，便盛情邀请我在课前为200多位同学即兴演讲，从大家的笑容中我知道效果还算不错。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p style="text-align: center">&lt;img data-s="300,640" data-type="png" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" class="img_loading" data-ratio="0.580046403712297" data-w="431" src="https://pangyd.com/uploads/2017/08/44d5041f007d30a9.png">&lt;/p></description></item><item><title>jdk api 1.8_google 翻译手册下载</title><link>https://pangyd.com/post/10-jdk-api-1-8-google/</link><pubDate>Thu, 03 Aug 2017 19:16:15 +0800</pubDate><guid>https://pangyd.com/post/10-jdk-api-1-8-google/</guid><description>&lt;div style="margin:1.5rem 0;padding:1rem;background:var(--bg-elev);border:1px solid var(--line);border-radius:10px;display:flex;flex-wrap:wrap;gap:.75rem;align-items:center">
 &lt;span class="mono" style="font-size:.8rem;color:var(--fg-muted)">附件&lt;/span>
 &lt;a href="https://pangyd.com/downloads/ddf90033af5b197d_5d83de7b1cc56137f5f55d7439bf93c5.CHM" download style="font-weight:600">jdk api 1.8_google.CHM&lt;/a>
&lt;/div></description></item><item><title>关于Class.forName(“com.mysql.jdbc.Driver”)</title><link>https://pangyd.com/post/30-class-forname-com-mysql-jdbc-driver/</link><pubDate>Thu, 03 Aug 2017 17:14:46 +0800</pubDate><guid>https://pangyd.com/post/30-class-forname-com-mysql-jdbc-driver/</guid><description>&lt;p>传统的使用jdbc来访问数据库的流程为：&lt;br> Class.forName(“com.mysql.jdbc.Driver”);&lt;br> String url = “jdbc:mysql://localhost:3306/test?user=root&amp;amp;password=123456″;&lt;br> Connection con = DriverManager.getConnection(url);&lt;br> Statement statement = con.createStatement();&lt;/p>&lt;p>最开始使用的时候，不明白为什么首先要加载一个驱动类，之后就可以取得了Connection了，很好奇DriverManager是怎么获得那个驱动类的信息，后来看了下com.mysql.jdbc.Driver这个类的源代码，豁然开朗了。原来在com.mysql.jdbc.Driver类中有这么一段静态初始化代码：&lt;br> static {&lt;br> try {&lt;br> java.sql.DriverManager.registerDriver(new Driver());&lt;br> } catch (SQLException E) {&lt;br> throw new RuntimeException(“Can’t register driver!”);&lt;br> }&lt;br> }&lt;br> 也就是，在Class.forName加载完驱动类，开始执行静态初始化代码时，会自动新建一个Driver的对象，并调用DriverManager.registerDriver把自己注册到DriverManager中去。&lt;br>&lt;br>&lt;strong>ps1:&lt;/strong> Class.forName(String) 与ClassLoader.loadClass(String)的区别&lt;br> Class.forName(String): 加载类，并且执行类初始化；可以通过Class.forName(String, boolean, ClassLoader)第二个参数来仅仅加载类不执行初始化；&lt;br> ClassLoader.loadClass(String): 仅仅加载类，不执行类初始化；&lt;/p>&lt;p>&lt;strong>ps2:&lt;/strong> 有时会看到这种用法：&lt;br> Class.forName(“com.mysql.jdbc.Driver”).newInstance();&lt;br> 这是没有必要的，正如前述，静态初始化已经new了一个Driver的对象，注册到DriverManager中去，在此再建立一个Driver对象则是完全没有必要的，浪费空间。&lt;/p>&lt;p>&lt;strong>ps3:&lt;/strong> 结合ps1，Class.forName(“com.mysql.jdbc.Driver”);相当于：&lt;br> ClassLoader loader = Thread.currentThread().getContextClassLoader();&lt;br> Class cls = loader.loadClass(“com.mysql.jdbc.Driver”);&lt;br> cls.newInstance();&lt;br> 这种方法的问题同ps2, 浪费了一个Driver对象；&lt;/p>&lt;p>&lt;strong>ps4:&lt;/strong> 在java 6中，引入了service provider的概念，即可以在配置文件中配置service（可能是一个interface或者abstract class）的provider（即service的实现类）。配置路径是：/META-INF/services/下面。详细信息见：https://docs.oracle.com/javase/6/docs/technotes/guides/jar/jar.html#Service%20Provider&lt;br> 而java.sql.DriverManager也添加了对此的支持，因此，在JDK6中，DriverManager的查找Driver的范围为：&lt;br> 1）system property “jdbc.drivers” 中配置的Driver值；&lt;br> 2）用户调用Class.forName()注册的Driver&lt;br> 3）service provider配置文件java.sql.Driver中配置的Driver值。&lt;br> 因此，在jdk6中，其实是可以不用调用Class.forName来加载mysql驱动的，因为mysql的驱动程序jar包中已经包含了java.sql.Driver配置文件，并在文件中添加了com.mysql.jdbc.Driver.但在JDK6之前版本，还是要调用这个方法。&lt;/p></description></item><item><title>刷机教程</title><link>https://pangyd.com/post/29/</link><pubDate>Wed, 02 Aug 2017 19:30:46 +0800</pubDate><guid>https://pangyd.com/post/29/</guid><description>&lt;div>随着手机行业不断发展，越来越多人追求完美，而刷机正好可以弥补——但系很多人对于刷机却一无所知，那就让我来带你装13&lt;br>&lt;br>刷机方法主要有【软刷】【卡刷】【线刷】&lt;br>&lt;br>下面让我一一介绍各种方法&lt;br>&lt;br>&lt;img src="file:///C:\Users\庞玉栋\AppData\Local\Temp\S~LW`Y7C8DV}Q91QC%Q`6HH.png">小白建议【软刷】，因为这个确实安全性最高&lt;br>可以用【刷机精灵】&lt;br>刷机固然有风险有可能变砖,但几率不大，其原因有以下几点：&lt;br>1、电量不足&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;，刷机时要注意的事项之一就是手机电量，那是因为手机刷机过程中就像电脑系统重装突然断电了。&lt;br>&lt;br>2、刷机包没选对&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;，很多时候刷机都是由于刷机的问题引起的，刷机包本身有问题，导致刷机过程中手机直接变砖的可能性很大，所以刷机包要去正规的资源站找，而且还测试过的比较安全。【建议奇兔刷机https://m.rom.7to.cn/】&lt;br>&lt;br>3、刷机前要ROOT&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;，有些手机要刷机一些底包等，这些都是特别的一些机型，特别的版本手机刷机需要这个，一般手机不要那么麻烦的。&lt;br>&lt;/div></description></item><item><title>转载自【Java编程精选】20个非常有用的Java程序片段</title><link>https://pangyd.com/post/28-java20java/</link><pubDate>Wed, 02 Aug 2017 19:26:36 +0800</pubDate><guid>https://pangyd.com/post/28-java20java/</guid><description>&lt;p>&lt;span>下面是20个非常有用的Java程序片段，希望能对你有用。&lt;strong>内容比较早，有些函数可能过时了，但是总体思路是不错滴，供参考。&lt;/strong>&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>&lt;strong>&lt;span>1、字符串有整型的相互转换&lt;/span>&lt;/strong>&lt;/span>&lt;/p>&lt;pre>&lt;code class="">String a = String.valueOf(&lt;span class="">2&lt;/span>); &amp;nbsp; &lt;span class="">//integer to numeric string&lt;br>&lt;/span>&lt;span class="">int&lt;/span> i = Integer.parseInt(a); &lt;span class="">//numeric string to an int&lt;/span>&lt;/code>&lt;/pre>&lt;p>&lt;span>&lt;strong>&lt;span>2、向文件末尾添加内容&lt;/span>&lt;/strong>&lt;/span>&lt;br>&lt;/p>&lt;p>&lt;span>&lt;/span>&lt;/p>&lt;pre>&lt;code class="">BufferedWriter out = &lt;span class="">null&lt;/span>; &amp;nbsp; &amp;nbsp; &lt;span class="">try&lt;/span> { &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;out = &lt;span class="">new&lt;/span> BufferedWriter(&lt;span class="">new&lt;/span> FileWriter(”filename”, &lt;span class="">true&lt;/span>)); &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;out.write(”aString”); &amp;nbsp; &amp;nbsp; } &lt;span class="">catch&lt;/span> (IOException e) { &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span class="">// error processing code &amp;nbsp; &amp;nbsp; &lt;br>&lt;/span>} &lt;span class="">finally&lt;/span> { &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span class="">if&lt;/span> (out != &lt;span class="">null&lt;/span>) { &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;out.close(); &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;} &amp;nbsp; &amp;nbsp; }&lt;/code>&lt;/pre>&lt;p>&lt;span>&lt;strong>&lt;span>3、得到当前方法的名字&lt;/span>&lt;/strong>&lt;/span>&lt;/p></description></item><item><title>程序员之间的十八层鄙视网络</title><link>https://pangyd.com/post/27/</link><pubDate>Tue, 01 Aug 2017 20:59:15 +0800</pubDate><guid>https://pangyd.com/post/27/</guid><description>&lt;p>&lt;span>有人的地方就有江湖。程序员，是一个知识、智商、都异于常规行业的群体。自傲，清高，闷骚，也属于这个群体鲜明标签。&lt;/span>&lt;/p>&lt;p>&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p>&lt;span>程序员有时候很自我，这样就给自己一个盲目的优越感。特别在与其他程序员对比的时候，他总能找到在一两个地方优于你的地方，所以，程序员之间的鄙视网络，在程序员这个职位诞生之日起，就慢慢的形成了。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>时至今日，这张鄙视网络已经相当的庞大。互联网的江湖中，有好事者开始归纳这张网，现在我们就来看看这张日益巨大的鄙视网。&lt;/span>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;img class="" data-height="336" data-ratio="0.56" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-type="jpeg" data-w="600" data-width="600" title="图0：程序员之间的十八层鄙视网络" width="auto" _width="auto" src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-fail="0">&lt;/p>&lt;p>&lt;img class="" data-height="337" data-ratio="0.5616666666666666" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-type="jpeg" data-w="600" data-width="600" title="图1：程序员之间的十八层鄙视网络" width="auto" _width="auto" src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-fail="0">&lt;/p>&lt;p>&lt;img class="img_loading" data-height="338" data-ratio="0.5633333333333334" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-type="jpeg" data-w="600" data-width="600" title="图2：程序员之间的十八层鄙视网络" width="auto" _width="auto" src="https://pangyd.com/uploads/2017/08/44d5041f007d30a9.png">&lt;/p>&lt;p>&lt;img class="img_loading" data-height="337" data-ratio="0.5616666666666666" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-type="jpeg" data-w="600" data-width="600" title="图3：程序员之间的十八层鄙视网络" width="auto" _width="auto" src="https://pangyd.com/uploads/2017/08/44d5041f007d30a9.png">&lt;/p>&lt;p>&lt;img class="img_loading" data-ratio="0.45666666666666667" data-s="300,640" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-type="jpeg" data-w="600" width="auto" _width="auto" src="https://pangyd.com/uploads/2017/08/44d5041f007d30a9.png">&lt;/p>&lt;p>&lt;img class="img_loading" data-height="353" data-ratio="0.5883333333333334" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-type="jpeg" data-w="600" data-width="600" title="图5：程序员之间的十八层鄙视网络" width="auto" _width="auto" src="https://pangyd.com/uploads/2017/08/44d5041f007d30a9.png">&lt;/p>&lt;p>&lt;img class="img_loading" data-height="665" data-ratio="1.1083333333333334" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-type="jpeg" data-w="600" data-width="600" title="图6：程序员之间的十八层鄙视网络" width="auto" _width="auto" src="https://pangyd.com/uploads/2017/08/44d5041f007d30a9.png">&lt;/p>&lt;p>&lt;img class="" data-height="692" data-ratio="1.2673992673992673" data-src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-type="jpeg" data-w="546" data-width="546" title="图7：程序员之间的十八层鄙视网络" width="auto" _width="auto" src="https://pangyd.com/uploads/2017/08/74c10f869f038762.jpg" data-fail="0">&lt;/p></description></item><item><title>JS和jq研究资料</title><link>https://pangyd.com/post/9-jsjq/</link><pubDate>Tue, 01 Aug 2017 20:48:57 +0800</pubDate><guid>https://pangyd.com/post/9-jsjq/</guid><description>&lt;div style="margin:1.5rem 0;padding:1rem;background:var(--bg-elev);border:1px solid var(--line);border-radius:10px;display:flex;flex-wrap:wrap;gap:.75rem;align-items:center">
 &lt;span class="mono" style="font-size:.8rem;color:var(--fg-muted)">附件&lt;/span>
 &lt;a href="https://pangyd.com/downloads/bcefeeb810ebe5c9_8312532411cc2b6d217587d06cd30f3d.zip" download style="font-weight:600">JS和jq研究资料.zip&lt;/a>
&lt;/div></description></item><item><title>图片特效代码</title><link>https://pangyd.com/post/26/</link><pubDate>Mon, 31 Jul 2017 15:41:23 +0800</pubDate><guid>https://pangyd.com/post/26/</guid><description>&lt;p style="text-align: center">&lt;img src="https://pangyd.com/uploads/2017/07/59acb6db4f1d9cdf.png" alt="xz.PNG">&lt;br>&lt;/p>&lt;p style="text-align: center">点击浏览：&lt;a target="_self" href="https://pangyd.com/zl/web/xz/">点这里&lt;/a>&lt;/p>&lt;p style="text-align: center">点击下载：&lt;a target="_self" href="https://pangyd.com/zl/web/xz/xz.tar.gz">点这里&lt;/a>&lt;/p></description></item><item><title>转载自【数据猿】从硬件到软件，人工智能如何驱动文娱行业变革？</title><link>https://pangyd.com/post/25/</link><pubDate>Mon, 31 Jul 2017 15:36:32 +0800</pubDate><guid>https://pangyd.com/post/25/</guid><description>&lt;p>&lt;br>&lt;/p>&lt;p style="text-align: justify">&lt;span>7月28日，“达观数据开放日”首站上海站的活动在上海浦东软件园爱酷空间举行。本次活动围绕“人工智能助力文娱行业智能运营”的主题，喜马拉雅FM副总裁李海波、创业邦趋势学院院长张雷、梨视频副总裁徐戌雄和达观数据COO冯佳妮等出席了本次活动，从人工智能与文娱行业的内容运营的结合点切入，对整个行业的发展趋势以及与人工智能的结合进行了深入的探讨。&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>在“开放日”的演讲环节中，嘉宾们从音频、媒体和短视频这三个不同的角度切入，分享了各自领域的运营经验。&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>喜马拉雅FM总裁李海波首先介绍了喜马拉雅在人工智能方面所进行的努力。早在2015年4月，喜马拉雅FM就宣布与科大讯飞达成合作，二者联合推出语音开放平台，直接对接漫步者等各类硬件研发和生产企业，还将围绕互联网与移动互联网、车联网、智能硬件等诸多领域展开全面合作。&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>当时，科大讯飞与喜马拉雅FM都已各自研发了一些产品，如：科大讯飞的小柔、小智智能语音机器人，喜马拉雅FM的听书宝，与“童话大王”郑渊洁合作的舒克故事机等。&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>而在上个月，喜马拉雅FM刚刚正式发布了国内第一款全内容AI音箱“小雅”，并基于此提供一套基于语音交互的场景解决方案，这意味着巨头齐集的国内人工智能领域迎来了首个内容型选手。&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>对于这款人工智能音响，李海波的逻辑是这样的：目前所有的智能音响到今天为止都在智能两个字上做文章，试图去控制电视，做遥控，去开窗帘，帮你调空调的温度，让机器人扫地。但小雅音响的核心是以内容为出发，打通和优化用户体验。&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>值得注意的是，喜马拉雅FM推出的这款人工智能音响并没有与之前合作过的科大讯飞联合推出，而是和小米音响一样使用了猎户星空提供的语义分析服务。对于这一点，李海波则表示，小雅拥有内容方面的优势。&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>创业邦趋势学院院长张雷则从前沿科技媒体的角度提出了对人工智能未来发展的预期。站在第三波人工智能浪潮的基础上，张雷对整个行业的前沿发展趋势进行了总结。“人工智能发展有三大要素，一个是算法，一个是数据，还有一个是计算。”有了算法和数据，又能有一个稳定、高效满足海量数据吞吐的计算解决方案，人工智能的快速发展是必然的趋势。&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>从文娱行业的角度来说，张雷认为未来将是多业态、多渠道共生的局面。对用户进行个性化的推荐建模，并为其推送个性化的精准IP将成为发展的趋势，多类型的定制化产品提供将成为主流。&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>梨视频副总裁徐戌雄站在短视频平台的角度探讨了视频行业运营的思路：“短视频作为新兴的传递方式，其成功的一大关键在于能够提供适合现代用户的浏览节奏的内容。梨视频主打资讯短视频的概念，迅速得到了大量关注。”&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>徐戌雄从多个角度探讨了梨视频在短视频行业的整个布局策略，包括通过聚集个人拍客和机构拍客，全方位把握全球范围内的资讯热点，并确保视频质量；也包括应用人工智能技术，通过配置个性化推荐系统等功能，打造智能的用户理解和内容推送机制。&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>达观数据COO冯佳妮以直播为切入点，分享了达观数据作为文本技术服务商，为文娱行业客户提供人工智能服务的实际案例。&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>“通过接入人工智能服务，用户的内容点击率可以上升足足3倍，搜索无结果率下降可达90%，对用户体验和用户转化率都会有巨大提升。”冯佳妮介绍的实打实的案例和指标提升给大家带来非常直观的感受。从数据上可以明显地看到，个性化推荐对于文娱行业精准运营的提升效果是传统方法所完全无法比拟的。&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>作为国内领先的人工智能企业，达观数据在文字自动化处理领域拥有深厚的技术积累，达观的个性化推荐、垂直搜索引擎以及文本挖掘等服务受到广大企业认可，在娱乐、传媒、电商、金融、科技等行业得到广泛应用。&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>&lt;br>&lt;/span>&lt;/p>&lt;p style="text-align: justify">&lt;span>随着人工智能技术的快速发展，越来越多传统行业也开始享受到了人工智能带来的红利。在文化娱乐行业也是如此，只有不断升级技术，琢磨产品，才能跟得上时代发展的步伐。&lt;/span>&lt;/p></description></item><item><title>转载自【Java编程精选】给Java新手的一些建议----Java知识点归纳(J2EE and Web 部分)</title><link>https://pangyd.com/post/24-javajava-java-j2ee-and-web/</link><pubDate>Mon, 31 Jul 2017 15:33:12 +0800</pubDate><guid>https://pangyd.com/post/24-javajava-java-j2ee-and-web/</guid><description>&lt;p>&lt;span>J2EE（Java2 Enterprise Edition） 刚出现时一般会用于开发企业内部的应用系统，特别是web应用，所以渐渐，有些人就会把J2EE和web模式画上了等号。但是其实 J2EE 里面并不仅仅是web，可以看到很多其中的规范都是通用的，目的是为了高效开发出健壮的服务企业业务模式的应用系统。J2EE中也是可以没有web界面的应用，而现在面向大众用户开发的网站往往也会使用到很多的J2EE的技术，所以J2EE和web开发的概念都是融合在了一起了。&lt;/span>&lt;br>&lt;/p>&lt;p>　　我本人在JAVA开发刚入行的时候，也是做了不少web相关的项目，之后渐渐地web使用比较少了，现在web开发的技术日新月异，不过一些基础知识还是类似，所以也把这部分内容稍作整理，以期望可以给大家一些经验。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;span>这次主要涉及到的两大块内容: Web相关的， J2EE相关的技术&lt;/span>&lt;/p>&lt;p>&amp;nbsp;&lt;/p>&lt;p>&lt;span>Web部分:&lt;/span>&lt;/p>&lt;p>　　脱离开各种语言，纯粹和 web相关的就是这些: HTML，CSS，JavaScript。哪怕你不用Java开发，用C#、PHP或者Python，这些内容都是通用，这里主要偏重一些基础知识。&lt;/p>&lt;ul class="list-paddingleft-2">&lt;li>&lt;p>&lt;strong>HTTP协议，HTTPS协议&lt;/strong>&lt;/p>&lt;/li>&lt;/ul>&lt;p>　　我觉得做Web开发，HTTP是基础中的基础。在一开始的时候，开发者可能对于这个内容了解不是非常深入，只是有个初步的概念，这个没有问题，可以先从了解，简单使用开始。 不过一旦有了一些web开发经验之后，你就需要把这块内容深入理解吃透。只知道简单概念，没有深入了解，可能并不会影响你开始上手做web开发，但是一旦涉及到一些性能调优、系统架构等工作，就需要你对HTTP有一个深入的了解，才能把工作做好。&lt;/p>&lt;p>　　对于HTTP请求， 我主要会关注以下内容:&lt;/p>&lt;p>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; HTTP请求的模式: request/response&lt;/p>&lt;p>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; HTTP请求的方法：GET， POST， PUT，DELETE 等等&lt;/p>&lt;p>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 协议的具体格式: head + body&lt;/p>&lt;p>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 协议的各类返回码:1XX，2XX，3XX，4XX，5XX&lt;/p>&lt;p>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Header中一些主要属性的含义和使用场景&lt;/p>&lt;p>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; HTTPS协议&lt;/p>&lt;p>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Cookie的基本原理和使用场景&lt;/p>&lt;p>&amp;nbsp;&lt;/p>&lt;ul class="list-paddingleft-2">&lt;li>&lt;p>&lt;strong>HTML， CSS&lt;/strong>&lt;/p>&lt;/li>&lt;/ul>&lt;p>　　这是WEB开发的一个基础，如果公司有专门的前端开发人员，可能你就不需要做这块相关的内容。可能只需要准备一些服务，可以提供一些数据就行。不过要是公司没有专门的前端人员，那就需要你自己写简单的页面和简单的布局了。这种情况下，还是对HTML和CSS必须有个简单的了解才行。&lt;/p>&lt;p>　　HTML简单了解的话需要知道页面的结构，具体各个表单，标签的使用方法，CSS需要知道一些基本的选择器的编写和使用。但这也只能满足一些简单页面的要求。如果有更加复杂页面的开发需求，那对CSS+DIV的使用需要有更加深入的了解了，具体内容因为自己对这方面涉及不多，也不多说了，大家可以再找其他的参考资料。&lt;/p>&lt;p>&amp;nbsp;&lt;/p>&lt;ul class="list-paddingleft-2">&lt;li>&lt;p>&lt;strong>JavaScript：&lt;/strong>&lt;/p>&lt;/li>&lt;/ul>&lt;p>　　前端开发的语言，唯一的语言，就是JS。并且从中衍生出一个很优秀的框架jQuery。现在前端基本上只要有一点复杂度的，都会使用这两种技术。并且以jquery为基础，还有一些其他前台框架，提供了各种动态效果，还有表格，表单等一些常用的处理。近两年，AngularJS框架又开始火热起来，这个框架在前端实现了MVC的架构，给前端的开发带来了革命性的影响(但是不意味着所有的前端开发都应该要用这个)。这些都是很值得好好看一下。即便不是专攻前端开发的，但是对于这几个技术点，能够先了解一下基本情况，基本的原理，对于web开发来说，还是大有好处的。&lt;/p>&lt;p>　　因为自己对这个涉猎也不深入，所以也就不更多罗列了，以免误人子弟了。&lt;/p>&lt;p>&amp;nbsp;&lt;/p>&lt;ul class="list-paddingleft-2">&lt;li>&lt;p>&lt;strong>Webservice&lt;/strong>&lt;/p>&lt;/li>&lt;/ul>&lt;p>　　在现在的企业应用开发中，Webservice已经是个必备的工具了。在各个企业中，经过一段时间积累，会有很多不同种类的应用，这些应用可能都会使用不同的语言开发，并且需要相互之间的通讯。通讯的首选就是Webservice。前后台的交互，服务之间的交互，或者不同语言之间的交互，都可以使用Webservice这个技术。&lt;/p>&lt;p>　　Webservice的实现方式多种多样，两者共同点是大家都是以HTTP协议为基础的，都可以跨域，跨语言进行访问。&lt;/p>&lt;p>　　用的比较多的，一个是SOAP协议的方式。这是比较传统的webservice 的实现，这个协议比较重量级，发布者会将webservice以wsdl形式发布，调用者通过wsdl可以直接生成实体类等。对于调用者来说，“调用”这个步骤会更容易处理一些。不过SOAP形式也存在着消息量大，传输效率低等缺陷。SOAP协议本身的可选项比较多，比较复杂，各个属性设置略有差异会导致服务通讯的失败，需要在调试中需要花费更多的时间。&lt;/p>&lt;p>　　现在更加流行的是使用RESTFUL的Webservice。这种技术是简化了URL，或者说对URL做了一定格式的限定，同时配合上HTTP的各种method，包括有GET，POST，DELTE，PUT 等，来实现整体service的各种功能。一般传输的内容都是json格式的字符串。Restful的Webservice的优点在于这是一种更加轻量级的使用方式，传输效率更高，接口约定更加清晰，双方调试也会更加便利一些。缺点在于，json格式太灵活，所以双方都需要自行处理json中的各个参数。对于接口实体类的处理需要更多的逻辑和代码。&lt;/p></description></item><item><title>【分享】口才比文采重要，训练口才的16种绝技</title><link>https://pangyd.com/post/23-16/</link><pubDate>Sun, 30 Jul 2017 20:25:46 +0800</pubDate><guid>https://pangyd.com/post/23-16/</guid><description>&lt;p>&lt;b>&lt;i> 1、朗读朗诵。&lt;/i>&lt;/b>&lt;br>自己读书，大声地读出来。每天坚持朗读一些文章，既练习口齿清晰伶俐，又积累一些知识量信息量，更重要的是对身体大有裨益，清喉扩胸，纳天地之气，成浩然之身！大家多读一些积极向上的文章，特别是《世界上最伟大的推销员》，我们强烈建议大家能够读熟背透。每天坚持朗读半小时以上，坚持两年三年，你不是大师也成大师！&lt;br>&lt;p>镇。 &lt;/p>&lt;div>&lt;b>&lt;i> 2、对着镜子训练。&lt;/i>&lt;/b>&lt;br>&lt;p>建议你在自己的起居室中或是办公室某一墙面安装一大镜子，每天在朗读过程中，去对着镜子训练，训练自己的眼神，训练自己的表情，训练自己的肢体语言，这样效果更好。&lt;/p>&lt;div>&lt;b>&lt;i> 3、自我录音摄像。&lt;/i>&lt;/b>&lt;br>&lt;p>如果条件允许，我建议您每隔一周时间，把自己的声音和演讲过程拍摄下来，这样反复观摩，反复研究哪儿我卡壳了，哪儿手势没到位，哪儿表情不自然，天长日久，你的口才自然进步神速。看一次自己的摄像比上台十次二十次效果都好。&lt;/p>&lt;div>&lt;i> &lt;b>4、尝试躺下来朗读。&lt;/b>&lt;/i>&lt;br>&lt;p>如果你想练就一流的运气技巧，一流的共鸣技巧，我教你一个非常简单的方法，就是：躺下来大声读书！当我们躺下来时，必然就是腹式呼吸，而腹式呼吸是最好的练声练气方法。每天睡觉之前，躺在床上大声地朗读十分钟，每天醒来之前，先躺在床上唱一段歌，再起来。坚持一至两个月，你会觉得自己呼吸流畅了，声音洪亮了，音质动听了，更有穿透力了，更有磁性了！&lt;/p>&lt;div>&lt;b>&lt;i> 5、速读训练。&lt;/i>&lt;/b>&lt;br>这种训练目的，是在于锻炼人口齿伶俐，语音准确，吐字清晰。&lt;br>&lt;br>&lt;p>方法：找来一篇演讲辞或一篇文辞优美的散文。先拿来字典、词典把文章中不认识或弄不懂的字、词查出来，搞清楚，弄明白，然后开始朗读。一般开始朗读的时候速度较慢，逐次加快，一次比一次读得快，最后达到你所能达到的最快速度。读的过程中不要有停顿，发音要准确，吐字要清晰，要尽量达到发声完整。因为如果你不把每个字音都完整地发出来，那么，如果速度加快以后，就会让人听不清楚你在说些什么，快也就失去了快的意义。我们的快必须建立在吐字清楚、发音干净利落的基础上。我们都听过体育节目的解说专家宋世雄的解说，他的解说就很有“快”的功夫。宋世雄解说的“快”，是快而不乱，每个字，每个音都发得十分清楚、准确，没有含混不清的地方。我们希望达到的快也就是他的那种快，吐字清晰，发音准确，而不是为了快而快。&lt;/p>&lt;div>&lt;i>&lt;b> 6、即兴朗读。&lt;/b>&lt;/i>&lt;br>&lt;p>平时空闲时，你可以随便拿一张报纸，任意翻到一段，然后尽量一气呵成的读下去。而且，在朗读过程中，能够注意一下，上半句看稿子，下半句离开稿子看前面（假设前面有听众）。长期以往，你发现自己记忆力加强许多，快速理解力和即兴构思能力也在加强。&lt;/p>&lt;p>&lt;i>&lt;b>7、背诵法。&lt;/b>&lt;/i>&lt;/p>&lt;p>背诵，并不仅仅要求你把某篇演讲辞、散文背下来就算完成了任务，我们要求的背诵，一是要“背”，二还要求“诵”。这种训练的目的有两个：一是培养记忆能力，二是培养口头表达能力。尝试去背诵一些文章，一篇一篇地去完成。天长日久，那些文章字句自然就转化为自己的词语了，练到一定时间就能张口就来口出华章。所谓：熟读唐诗三百首，不会吟诗也会吟！&lt;/p>&lt;/div>&lt;/div>&lt;/div>&lt;/div>&lt;/div>&lt;div>&lt;i>&lt;b>8、复述法&lt;/b>&lt;/i>。&lt;br>&lt;p>复述法简单地说，就是把别人的话重复地叙述一遍。可以找一位伙伴一起训练。首先，请对方随便讲一个话题，或是一个故事。自己先注意倾听。然后再向对方复述一遍。这种练习在于锻炼语言的连贯性及现场即兴构思能力，和语言组织能力。如果能面对众人复述就更好了，它还可以锻炼你的胆量，克服紧张心理。 &lt;/p>&lt;div>&lt;i>&lt;b> 9、模仿法。&lt;/b>&lt;/i>&lt;br>&lt;p>我们每个人从小就会模仿，模仿大人做事，模仿大人说话。其实模仿的过程也是一个学习的过程。我们小时候学说话是向爸爸、妈妈及周围的人学习，向周围的人模仿。那么我们练口才也可以利用模仿法，向这方面有专长的人模仿。这样天长日久，我们的口语表达能力就能得到提高。&lt;/p>&lt;div>&lt;i>&lt;b> 10、描述法。&lt;/b>&lt;/i>&lt;br>&lt;p>小的时候我们都学过看图说话，描述法就类似于这种看图说话，只是我们要看的不仅仅是书本上的图，还有生活中的一些景、事、物、人，而且要求也比看图说话高一些。简单地说，描述法也就是把你看到的景、事、物、人用描述性的语言表达出来。描述法可以说是比以上的几种训练法更进一步。这里没有现成的演讲辞、散文、诗歌等做你的练习材料，而要求你自己去组织语言进行描述。所以描述法训练的主要目的就在于训练同学们的语言组织能力和语言的条理性。在描述时，要能够抓住特点进行描述。语言要清楚，明白，要有一定的文采。一定要用描述性的语言，尽量生动些，活泼些。这可以训练我们积累优美词语的应用能力。&lt;/p>&lt;p>&lt;b>&lt;i>11、角色扮演法。&lt;/i>&lt;/b>&lt;/p>&lt;p>在我们的培训过程中，经常让学员进行角色扮演，组织角色语言去演讲，叫“情境模拟训练法”，比如扮演律师，扮演市长答记者问，扮演领导开动员会，扮演新郎新娘即兴发言等等，还可以选择小品中的角色扮演，直接让学员去演小品，去扮演作品中出现的不同的人物，当然这个扮演主要是在语言上的扮演。这种训练的目的，在于培养人的语言的适应性、个性，以及适当的表情、动作。&lt;/p>&lt;div>&lt;b>&lt;i> 12、讲故事法。&lt;/i>&lt;/b>&lt;br>&lt;p>我们的口才培训，要求学员能够讲100个以上的故事，不同时候要能够讲不同的故事，而且现场就能想出符合场合的故事。这就要求我们积累大量的素材。同时还要讲得动听，讲得精彩，熟能生巧，讲多了口才就来了！&lt;/p>&lt;div>&lt;b>&lt;i> 13、积累知识，多翻翻字典、成语词典。&lt;/i>&lt;/b>&lt;br>建议各位办公桌上和家里都放一本《新华字典》和《现代汉语成语词典》，有空就翻翻，不认识的字多看看，认识的字也再看细些，你会发现中国的文字博大精深，坚持下去，你的词汇量会越来越多，你的口才自然越来越棒！&lt;br>&lt;/div>&lt;/div>&lt;div> &lt;b>&lt;i>14、对口才产生兴趣。&lt;/i>&lt;/b>&lt;br>&lt;p>兴趣是最好的老师。当你的焦点在口才训练上时，你必然就会关注平时生活工作中的口才技巧。兴趣在哪里，焦点到哪里；焦点到哪里，学问到哪里！这种方法进步更快。即使看电视，也在注意台词的优美，交际的仪态，幽默的笑眼，必然进步神快！&lt;/p>&lt;p>&lt;b>&lt;i>15、写日记。&lt;/i>&lt;/b>&lt;/p>&lt;p>写日记是最好的自我沟通的方法，每天写上一千来字，既整理自己的思路，反省当日之进步与不足，梳理自己的情绪，释放一些不快，又可以学会遣词造句，天长日久，手能写之，口必能言之。&lt;/p>&lt;/div>&lt;/div>&lt;/div>&lt;/div>&lt;div>&lt;i>&lt;b> 16、多找机会上台。&lt;/b>&lt;/i>&lt;br>很多同学认为生活中缺少锻炼的舞台，没有公众场合发言的机会。其实，这是一种误区，我们平时生活工作中，公众演讲的机会太多了，只是我们没有发现，没有这个意识去参与。&lt;br>&lt;br>&lt;p>如果你想突破口才瓶颈，你一定要多找机会讲话。每次开会，必定坐第一排，必定要举手发表一下自己的观点；有机会就给自己的员工、小组成员开开会；有机会还可以开开家庭会议，把家庭打造在学习口才的舞台；现在每逢节假日，路演比较流行，那一有机会你就上台去参与，不要管那么多，你只是在锻炼自己而已！放下自己，放下一切时，你发现学习口才就这么简单！&lt;/p>&lt;div>&lt;p style="text-align: center">&lt;b> 学习口才最“吊诡”的地方在于：很多人知道、明白、了解、懂得，但是仍然开不了口，无法去表达！&lt;br>&lt;p style="text-align: center">&lt;b>——因为，“知识”不等于能力！能力，一定是训练出来的！&lt;/b>&lt;/p>&lt;p style="text-align: center">&lt;b>&lt;img src="https://pangyd.com/uploads/2017/07/e107e0c578f56a27.jpeg" alt="1501417580706.jpeg">&lt;/b>&lt;/p>&lt;/b>&lt;/p>&lt;/div>&lt;/div>&lt;/p></description></item><item><title>转载自【Yidu】《如何搭建一个茉莉机器人》</title><link>https://pangyd.com/post/22-yidu/</link><pubDate>Sun, 30 Jul 2017 20:19:39 +0800</pubDate><guid>https://pangyd.com/post/22-yidu/</guid><description>&lt;div>&lt;p>&lt;img src="https://pangyd.com/uploads/2017/07/870b74962f409833.jpeg" alt="1501417331353.jpeg">&lt;br>&lt;/p>&lt;p>源码简介:茉莉QQ机器人采用Smart&amp;nbsp;QQ接口，程序由PHP+MySQL开发，机器人在运行期间可以累积在线天数哦，但是您不能在机器人运行期间用电脑登录QQ，不然会把机器人挤下线，但是手机QQ可以登录，互不干扰。&lt;/p>&lt;br>好了话不多说，我们开始吧&lt;br>&lt;br>首先呢你要有空间，随便找个空间&lt;br>建议用这个空间&lt;a target="_self" href="https://yidc.vu4.pw/ ">https://yidc.vu4.pw/&amp;nbsp;&lt;/a>，注册送一块钱，然后往下滑有个一元主机，用那个就行&lt;br>然后下载茉莉机器人的源码，源码下载地址:&lt;a target="_self" href="https://pan.baidu.com/s/1eS3VlCI">https://pan.baidu.com/s/1eS3VlCI&lt;/a>&lt;br>&lt;br>教程开始:首先在我给你的那个网站开空间，ftp账号密码必须都记住，最好弄一样的，后面方便操作！&lt;br>&lt;br>开好空间以后点击管理，然后有个面板控制，点进去&lt;br>然后上边有个在线文件，把我给你的源码上传&lt;br>&lt;br>上传完成之后解压到web的文件夹，密码不用填&lt;br>&lt;br>那个控制面板有个域名绑定&lt;br>&lt;br>然后点进去域名，按照步骤安装，数据库的账号用户名密码就是刚才的ftp账号密码。&lt;br>&lt;br>之后一个你自己的机器人网站就搭建好&lt;br>&lt;br>&lt;img src="https://pangyd.com/uploads/2017/07/3566cd8e25e67f7b.jpeg" alt="1501417332673.jpeg">&lt;br>&lt;/div></description></item><item><title>表白页面制作</title><link>https://pangyd.com/post/21/</link><pubDate>Sat, 29 Jul 2017 19:12:02 +0800</pubDate><guid>https://pangyd.com/post/21/</guid><description>&lt;p>&lt;img src="https://pangyd.com/uploads/2017/07/83a029631fb0b786.png" alt="bb.PNG">&lt;/p>&lt;p>演示地址：&lt;a target="_self" href="https://pangyd.com/zl/web/bb/">点这里&lt;/a>&lt;/p>&lt;p>下载地址：&lt;a target="_self" href="https://pangyd.com/zl/web/bb/bb.tar.gz">点这里&lt;/a>&lt;/p></description></item><item><title>文字搬运工代码</title><link>https://pangyd.com/post/20/</link><pubDate>Sat, 29 Jul 2017 19:01:42 +0800</pubDate><guid>https://pangyd.com/post/20/</guid><description>&lt;p>&lt;img src="https://pangyd.com/uploads/2017/07/460edad1355c680d.png" alt="wz.PNG">&lt;br>&lt;/p>&lt;p>演示地址：&lt;a target="_self" href="https://pangyd.com/zl/web/wz/">点这里&lt;/a>&lt;/p>&lt;p>下载地址：&lt;a target="_self" href="https://pangyd.com/zl/web/wz/wz.tar.gz">点这里&lt;/a>&lt;/p>&lt;p>前端&lt;/p>&lt;p>&lt;span class="Apple-tab-span">	&lt;/span>HTML5 &amp;nbsp; &amp;nbsp; 网页内容&lt;/p>&lt;p>&lt;span class="Apple-tab-span">	&lt;/span>CSS3 &amp;nbsp; &amp;nbsp; &amp;nbsp;样式美化&lt;/p>&lt;p>&lt;span class="Apple-tab-span">	&lt;/span>JS/Jquery 特效、验证等&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>前端开发工具&lt;/p>&lt;p>webstorm10&lt;/p>&lt;p>dw&lt;/p>&lt;p>sublime&lt;/p>&lt;p>记事本&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>思路：&lt;/p>&lt;p>（1）判断左侧是否输入内容，如果没有输入内容，则提示&lt;/p>&lt;p>（2）超链接点击后，显示内容的总个数&amp;lt;span id="all"&amp;gt;&lt;/p>&lt;p>（3）超链接点击后，移动左侧内容到右侧，改变当前数字&amp;lt;span id="current"&amp;gt;&lt;/p>&lt;p>&lt;span class="Apple-tab-span">	&lt;/span>（3-1）如何移动内容&lt;/p>&lt;p>&lt;span class="Apple-tab-span">		&lt;/span>自动循环做下面两个事：setInterval(事情，80)&lt;/p>&lt;p>&lt;span class="Apple-tab-span">			&lt;/span>获取左侧内容，移动左侧内容的第一个内容&lt;/p>&lt;p>&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class="Apple-tab-span">	&lt;/span>更新左侧内容&lt;/p>&lt;p>（4）完善细节&lt;/p>&lt;p>&lt;span class="Apple-tab-span">	&lt;/span>（4-1）超链接链接后，橘黄色变浅，文字移动完毕后，超链接恢复橘黄色&lt;/p>&lt;p>&lt;span class="Apple-tab-span">	&lt;/span>（4-2）进度条显示，并动态效果&lt;/p>&lt;div>&lt;br>&lt;/div></description></item><item><title>新闻导航设计</title><link>https://pangyd.com/post/19/</link><pubDate>Sat, 29 Jul 2017 18:50:26 +0800</pubDate><guid>https://pangyd.com/post/19/</guid><description>&lt;p>&lt;br>&lt;/p>&lt;p>&lt;img src="https://pangyd.com/uploads/2017/07/f85ef54aea7b99e0.png" alt="xw.PNG">&lt;/p>&lt;p>演示地址：&lt;a target="_self" href="https://pangyd.com/zl/web/xw/">点这里&lt;/a>&lt;/p>&lt;p>下载素材：&lt;a target="_self" href="https://pangyd.com/zl/web/xw/js.tar.gz">点这里&lt;/a>&lt;/p></description></item><item><title>Tomcat配置用户名和密码</title><link>https://pangyd.com/post/18-tomcat/</link><pubDate>Sat, 29 Jul 2017 12:47:51 +0800</pubDate><guid>https://pangyd.com/post/18-tomcat/</guid><description>&lt;ol class="exp-conent-orderlist">&lt;li class="exp-content-list list-item-1">&lt;div class="list-icon">&lt;/div>&lt;div class="content-list-text">&lt;p>1.在浏览器输入http://localhost:8080/，打开Tomcat自带的默认主页面，右侧有“administration”“documentation”等模块。选择“administration”下面的Tomcat Manager，提示需要输入用户名和密码。&lt;/p>&lt;/div>&lt;div class="content-list-media">&lt;div class="content-list-image clearfix">2.在不知道用户名和密码的情况下，Tomcat Manager的用户名和密码可以到“Tomcat安装目录/conf/tomcat-users.xml”文件中进行查看。&lt;/div>&lt;/div>&lt;/li>&lt;li class="exp-content-list list-item-2">&lt;div class="content-list-text">&lt;p>3.默认情况下，Tomcat Manager的用户名和密码是注释掉的（在&amp;lt;!--用户名密码--&amp;gt;），即Tomcat Manager默认是禁用的。&lt;/p>&lt;/div>&lt;div class="content-list-media">&lt;div class="content-list-image clearfix">4.要使用Tomcat Manager，就要对用户进行配置（或取消注释符即可使用已配置的用户）。对用户的配置需要放在&amp;lt;tomcat-users&amp;gt;和&amp;lt;/tomcat-users&amp;gt;之间。重新启动Tomcat服务，再到Tomcat主页面点击“Tomcat Manager”，输入配置的用户名和密码，点击确定就可以进入到“Tomcat Web Application Manager”界面。&lt;/div>&lt;/div>&lt;/li>&lt;li class="exp-content-list list-item-4">&lt;div class="content-list-media">&lt;p>&lt;b>&lt;i>注意事项&lt;/i>&lt;/b>&lt;/p>&lt;/div>&lt;/li>&lt;li class="exp-content-list list-item-4">&lt;div class="exp-content-block">&lt;h2 class="exp-content-head">&lt;div class="audio-wp audio-wp-2" data-for="" data-text="" data-index="3">&lt;span class="audio-inner">&lt;span class="audio-icon">&lt;/span>&lt;span class="audio-icon-2">&lt;/span>&lt;span class="audio-icon-3">&lt;/span>&lt;/span>&lt;span class="desc">&lt;/span>&lt;/div>&lt;/h2>&lt;div class="exp-content-body">&lt;ul class="exp-content-unorderlist ">&lt;li class="exp-content-list list-item-1">&lt;div class="content-list-text">Tomcat Manager的用户名和密码配置在“Tomcat安装目录/conf/tomcat-users.xml”文件中查看和配置。&lt;/div>&lt;/li>&lt;/ul>&lt;/div>&lt;/div>&lt;/li>&lt;/ol></description></item><item><title>tomact自启动设置</title><link>https://pangyd.com/post/17-tomact/</link><pubDate>Sat, 29 Jul 2017 11:56:14 +0800</pubDate><guid>https://pangyd.com/post/17-tomact/</guid><description>&lt;p>&lt;span>	&lt;/span>该部分内容来源于网络，本人测试，功能正常，留下备忘。&lt;/p>&lt;p>&amp;nbsp;&lt;/p>&lt;p>&lt;strong>&lt;span>	&lt;/span>适用于&lt;span class="hl1">Tomcat&lt;/span>4.1、5.5、6.0。&lt;/strong>&lt;/p>&lt;br>&lt;p>因为解压缩版的&lt;span class="hl1">Tomcat&lt;/span>，在windows服务上没有启动项，所以需要手动添加，然后可以设置开机启动&lt;span class="hl1">tomcat&lt;/span>。&lt;/p>&lt;p>一、安装服务&lt;/p>&lt;p>在命令行中进入/&lt;span class="hl1">Tomcat&lt;/span>路径/bin/，执行“service.bat install”：（开始-运行,输入cmd,cd&lt;span class="hl1">Tomcat&lt;/span>路径/bin,service.bat install）。到此为止windows服务上就增加了一个&lt;span class="hl1">tomcat&lt;/span>服务&lt;/p>&lt;p>?&lt;/p>&lt;p>说明：&lt;/p>&lt;p>1、服务名和显示名称：service.bat中设置了默认的服务名称，不同版本分别命名为&lt;span class="hl1">Tomcat&lt;/span>4、&lt;span class="hl1">Tomcat&lt;/span>5、&lt;span class="hl1">Tomcat&lt;/span>6，如果需要自定义服务名或服务的显示名称，可在service.bat中修改SERVICE_NAME或PR_DISPLAYNAME；&lt;/p>&lt;p>2、防火墙的影响：/bin/&lt;span class="hl1">tomcat&lt;/span>6.exe（或&lt;span class="hl1">tomcat&lt;/span>4.exe、&lt;span class="hl1">tomcat&lt;/span>5.exe）将被作为服务程序，如果有防火墙，需要设为允许作为服务。&lt;/p>&lt;p>二、卸载服务&lt;/p>&lt;p>在命令行中进入/&lt;span class="hl1">Tomcat&lt;/span>路径/bin/，执行“service.bat remove”：&lt;/p>&lt;p>&lt;a href="https://tomcat.apache.org/tomcat-6.0-doc/windows-service-howto.html" target="_blank">&lt;/a>&lt;/p>&lt;p>三、命令行参数&lt;/p>&lt;p>&lt;span class="hl1">Tomcat&lt;/span>的服务名、Jvm内存初始值和最大值等可通过命令行参数设置，请参考官方文档：&lt;a href="https://tomcat.apache.org/tomcat-5.5-doc/windows-service-howto.html" target="_blank">&lt;/a>&lt;/p>&lt;p>http://&lt;span class="hl1">tomcat&lt;/span>.apache.org/&lt;span class="hl1">tomcat&lt;/span>-5.5-doc/windows-service-howto.html&lt;/p>&lt;p>&lt;a href="https://tomcat.apache.org/tomcat-6.0-doc/windows-service-howto.html" target="_blank">http://&lt;span class="hl1">tomcat&lt;/span>.apache.org/&lt;span class="hl1">tomcat&lt;/span>-6.0-doc/windows-service-howto.html&lt;/a>&lt;/p>&lt;p>?&lt;/p>&lt;p>四、开机启动&lt;span class="hl1">Tomcat&lt;/span>设置&lt;/p>&lt;p>开始-控制面板-管理工具-服务&lt;/p>&lt;p>找到apche&amp;nbsp;&lt;span class="hl1">tomcat&lt;/span>?右键属性，把手动改为自动&lt;/p></description></item><item><title>JavaEE (my eclipse10 以及 tomcat6配置教程)</title><link>https://pangyd.com/post/16-javaee-my-eclipse10-tomcat6/</link><pubDate>Sat, 29 Jul 2017 10:56:56 +0800</pubDate><guid>https://pangyd.com/post/16-javaee-my-eclipse10-tomcat6/</guid><description>&lt;p style="text-align: center">&lt;b>&lt;i>所需工具:&lt;/i>&lt;/b>&lt;/p>&lt;p style="text-align: center">(建议使用迅雷下载)&lt;/p>&lt;p style="text-align: center">配置好的Java环境：&lt;a target="_self" href="https://pangyd.com/post/15-java/">点击浏览&lt;/a>&lt;/p>&lt;p style="text-align: center">My Eclipse破解版：&lt;a target="_self" href="https://pangyd.com/zl/Myeclipse10.7.1+破解文件.zip">点击下载&lt;/a>&amp;nbsp;（下载完成后 按照压缩包里面的教程下载和安装My eclipse 自测成功！）&lt;/p>&lt;p style="text-align: center">tomcat6.0:&lt;a target="_self" href="https://pangyd.com/zl/apache-tomcat-6.0.20.zip">点击下载&lt;/a>&lt;/p>&lt;p style="text-align: center">&lt;b>&lt;i>tomcat在My Eclipse下的环境配置：&lt;/i>&lt;/b>&lt;/p>&lt;p style="text-align: center">1.首先将下载好的压缩包解压 解压到c盘的根目录下&lt;/p>&lt;ol class="exp-conent-orderlist">&lt;li class="exp-content-list list-item-10">&lt;div class="content-list-text">&lt;ol class="exp-conent-orderlist">&lt;li class="exp-content-list list-item-10">&lt;div class="content-list-text">&lt;p style="text-align: center">2.接下来开始配置环境变量，&lt;/p>&lt;p style="text-align: center">3.然后新建三个系统变量：&lt;/p>&lt;p style="text-align: center">TOMCAT_HOME=C:\apache-tomcat-6.0.20&lt;/p>&lt;p style="text-align: center">CATALINA_HOME=C:\apache-tomcat-6.0.20&lt;/p>&lt;p style="text-align: center">CATALINA_BASE=C:\apache-tomcat-6.0.20&lt;/p>&lt;/div>&lt;/li>&lt;li class="exp-content-list list-item-10">&lt;p style="text-align: center">如图（变量值为39改成20）&lt;/p>&lt;/li>&lt;li class="exp-content-list list-item-10">&lt;ol class="exp-conent-orderlist">&lt;li class="exp-content-list list-item-10">&lt;div class="content-list-media">&lt;p style="text-align: center">&lt;a class="exp-image-wraper" href="https://jingyan.baidu.com/album/86f4a73e5be03237d65269ef.html?picindex=17" target="_self">&lt;br>&lt;/a>&lt;a class="exp-image-wraper" href="https://jingyan.baidu.com/album/86f4a73e5be03237d65269ef.html?picindex=18" target="_self">&lt;br>&lt;/a>&lt;a class="exp-image-wraper" href="https://jingyan.baidu.com/album/86f4a73e5be03237d65269ef.html?picindex=19" target="_self">&lt;/a>&lt;/p>&lt;ol class="exp-conent-orderlist">&lt;li class="exp-content-list list-item-11" style="text-align: center">&lt;/li>&lt;/ol>&lt;p style="text-align: center">&lt;a class="exp-image-wraper" href="https://jingyan.baidu.com/album/86f4a73e5be03237d65269ef.html?picindex=20" target="_self">&lt;br>&lt;/a>&lt;a class="exp-image-wraper" href="https://jingyan.baidu.com/album/86f4a73e5be03237d65269ef.html?picindex=21" target="_self">&lt;/a>&lt;a class="exp-image-wraper" href="https://jingyan.baidu.com/album/86f4a73e5be03237d65269ef.html?picindex=21" target="_self">&lt;/a>&lt;/p>&lt;p>&lt;/p>&lt;/div>&lt;/li>&lt;/ol>&lt;/li>&lt;li class="exp-content-list list-item-10">&lt;ol class="exp-conent-orderlist">&lt;li class="exp-content-list list-item-11">&lt;div class="content-list-text">&lt;p style="text-align: center">4.在CLASSPALL中的最后添加;%TOMCAT_HOME%\lib\servlet-api.jar;&lt;/p>&lt;p style="text-align: center">5.在PAth中最前添加;%CATALINA_HOME%\bin;&lt;/p>&lt;p style="text-align: center">&amp;nbsp;注意：前后顺序不影响&lt;/p>&lt;/div>&lt;/li>&lt;li class="exp-content-list list-item-11">&lt;ol class="exp-conent-orderlist">&lt;li class="exp-content-list list-item-12">&lt;div class="content-list-text">&lt;p style="text-align: center">至此，配置工作完成！打开bin文件夹，双击startup.bat&lt;/p>&lt;p style="text-align: center">它会自动打开如下控制台界面。&lt;/p>&lt;p style="text-align: center">不要关闭控制台界面，打开浏览器，输入http://localhost:8080&amp;nbsp;&lt;/p>&lt;p style="text-align: center">出现Tomcat的网页，证明安装并配置成功！&lt;/p>&lt;p style="text-align: center">最后关闭控制台，关闭控制台即关闭Tomcat服务&lt;/p>&lt;/div>&lt;/li>&lt;li class="exp-content-list list-item-12">&lt;p style="text-align: center">&lt;b>&lt;i>接下来配置在my eclipse中配置tomcat6&lt;/i>&lt;/b>&lt;/p>&lt;/li>&lt;li class="exp-content-list list-item-12">&lt;p style="text-align: center">&lt;b>&lt;i>首先确保你已经成功的安装 了myeclipse10和tomcat&lt;/i>&lt;/b>&lt;/p></description></item><item><title>Java简介和安装教程</title><link>https://pangyd.com/post/15-java/</link><pubDate>Sat, 29 Jul 2017 10:16:04 +0800</pubDate><guid>https://pangyd.com/post/15-java/</guid><description>&lt;p>简介&lt;/p>&lt;p>Java是一门面向对象编程语言，不仅吸收了C++语言的各种优点，还摒弃了C++里难以理解的多继承、指针等概念，因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的代表，极好地实现了面向对象理论，允许程序员以优雅的思维方式进行复杂的编程 。&lt;/p>&lt;p>Java具有简单性、面向对象、分布式、健壮性、安全性、平台独立与可移植性、多线程、动态性等特点 &amp;nbsp;。Java可以编写桌面应用程序、Web应用程序、分布式系统和嵌入式系统应用程序等&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>环境配置教程：&lt;/p>&lt;p>&lt;/p>&lt;p>1、下载 JDK1.8:：&lt;a target="_self" href="https://pangyd.com/zl/jdk-8u131-windows-x64.exe">点击下载&lt;/a>&lt;/p>&lt;br>2、安装JDK&lt;p>&lt;/p>&lt;p>直接运行exe可执行程序，默认安装即可；&lt;br>备注：路径可以选其他盘符，不建议路径包含中文名及特殊符号。&lt;/p>&lt;p>3、配置环境变量&lt;/p>&lt;p>win10下打开环境变量：此电脑（右击属性）-高级系统设置-环境变量&lt;/p>&lt;p>&lt;/p>&lt;p>1新建变量名：JAVA_HOME，变量值：C:\Program Files\Java\jdk1.8.0_131&lt;/p>2 打开PATH，添加变量值：%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin&lt;br>3新建变量名：CLASSPATH，变量值：.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar&lt;p>&lt;/p>&lt;p>&lt;br>&lt;strong>备注：&lt;/strong>&lt;br>1.表示当前路径，%JAVA_HOME%就是引用前面指定的JAVA_HOME；&lt;br>2 JAVA_HOME指明JDK安装路径，此路径下包括lib，bin，jre等文件夹，tomcat，eclipse等的运行都需要依靠此变量。&lt;br>3 PATH使得系统可以在任何路径下识别java命令。&lt;br>4 CLASSPATH为java加载类(class or lib)路径，只有类在classpath中，java命令才能识别。&lt;/p>&lt;p>4、测试jdk&lt;/p>&lt;p>在CMD命令窗口下输入javac java javadoc命令，出现如下界面，则安装成功。&lt;/p>&lt;p>5,安装eclipse：&lt;a target="_self" href="https://pangyd.com/zl/eclipse-java-mars-win32.zip">点击下载&lt;/a>&lt;/p>&lt;p>下载完成解压 点击 eclipse.exe 文件即可运行&lt;/p>&lt;div class="para" label-module="para">&lt;br>&lt;/div></description></item><item><title>清除QQ资料教程</title><link>https://pangyd.com/post/14-qq/</link><pubDate>Mon, 24 Jul 2017 17:36:30 +0800</pubDate><guid>https://pangyd.com/post/14-qq/</guid><description>&lt;p style="text-align: center">&lt;/p>&lt;p>今天看到名片不够简洁强迫症作祟，上网查了下教程没有一个能行，然后又想到很久很久以前老年机可以改性别啥的，回到家找到了老年机却坏了，最后我想到用java模拟器能模拟老版机，废话不多说让我们进入正题&lt;/p>&lt;p>需要材料:联网电脑一台(安卓4.4-5.0的可以去网上下载安卓版java模拟器用我这个qq.jar也是能使用的)&lt;/p>&lt;div>&lt;br>&lt;/div>1.下载所需文件mnq.zip到电脑桌面&lt;br>2.解压mnq.zip 里面有个java.zip(java模拟器)和qq.jar。&lt;br>3.打开java.zip解压出的文件夹，找到KEmulator.exe&lt;br>4.打开KEmulator.exe&lt;br>5.点软件菜单栏的那个文件-载入jar&lt;br>6.在搜索栏输入桌面，然后下拉找到解压出来的qq.jar并打开&lt;br>7.童年回忆出现了，[这里全程用模拟键盘操作哦]第一次进来要设置qq号和密码，点软件菜单栏&amp;nbsp;视图-模拟键盘&lt;br>8.输入好qq密码即可登录&lt;br>9.菜单-我的资料-个人资料&lt;br>10.往下翻，找到年龄，出生日期那些东西，全部选-即可，点击修改，提示修改成功&lt;br>&lt;p>11.打开qq查看资料，可以看到资料啥都没了，是不是很棒棒啊&lt;img src="https://pangyd.com/uploads/2017/07/7057549439f9fb6f.gif" alt="[耶]">&lt;/p>&lt;p>&lt;/p>&lt;p style="text-align: center">&lt;img src="https://pangyd.com/uploads/2017/07/e3d0f352de14b86f.png" alt="捕获.PNG">&lt;br>&lt;/p>&lt;br>&lt;p style="text-align: center">分割线&lt;/p>&lt;p style="text-align: center">----------------------------------------------------------------------------————————————————————————————————————————————————————————————————————————————————————————————&lt;/p>&lt;p style="text-align: center">下载资料：&lt;a target="_self" href="https://pangyd.com/index/download/show/id/7.html">点击下载&lt;/a>&lt;/p>&lt;p style="text-align: center">&lt;br>&lt;/p></description></item><item><title>什么叫真正的用户体验</title><link>https://pangyd.com/post/12/</link><pubDate>Sun, 02 Apr 2017 16:22:25 +0800</pubDate><guid>https://pangyd.com/post/12/</guid><description>&lt;p style="text-align: center">&lt;img src="https://pangyd.com/uploads/2017/06/0bcd4237e4bca96c.jpg" alt="f3bb78a307a3ca077ebd0da63816d57d.jpg">&lt;br>&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>什么叫真正的用户体验？很多人把这个词挂在嘴边，却鲜有人真正研究过。对于我们的用户，扪心自问，我们是否真正地站在用户的角度思考过?&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>我们认真思考过用户从接到包裹到使用产品中的每一个环节都会做什么吗？用户的需求是什么？除了满足用户的需求之外还能为用户提供什么？下面来告诉大家什么是真正的用户体验。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>用户体验是一种纯主观的感受，是在用户接触产品或服务的整个过程中形成的综合体验。好的用户体验一定要注重细节，并且贯穿于每一个细节，这种细节一定要一让用户能够感知到，并且这种感知要超出用户的预期，给用户带来惊喜。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>举个简单的例子，我们平时在上网的时候，无论是看微博、刷论坛还是购物等，总免不了来回翻页。于是有人就设计了一种全新的浏览方式—“瀑布流”，网页的页面会随着用户的下拉不断地刷新出新的内容，这样一来，用户就无须频繁地翻页，紧紧滑动鼠标的滚轮就可以不断看到新的内容，这便是网页制作者在用户体验方面的改进，给使用者的感觉就很方便、很舒服。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>所以当打开一个网站时，用户体验度时非常重要的，它直接决定着用户在网站停留时间的长短，停留时间越长，产生交易的可能性就越大。提醒大家在建设网站时，一定要站在用户的角度去做好每一步，做到真正替用户思考！&lt;/p></description></item><item><title>关于网站建设备案的流程与疑问</title><link>https://pangyd.com/post/11/</link><pubDate>Sun, 02 Apr 2017 16:10:46 +0800</pubDate><guid>https://pangyd.com/post/11/</guid><description>&lt;p>&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;建设网站都会遇到一个问题-是否提交备案。关于备案有许多人觉得重要，当然也有许多人觉得不重要（直接选择个国外服务器），在做网站建设服务的时候，也会遇到一些企业主觉得网站备案的周期比较长，耽误网站上线时间，影响推广周期。到底要不要备案？关于备案的流程与疑问，元大人为大家详细分享一下备案的内容。&lt;/p>&lt;p>　　我是建议所有的企业用户都需要备案而个人用户根据网站的目的与规划酌情考虑。&lt;/p>&lt;p>　　一、备案答疑&lt;/p>&lt;p>　　1.为什么说企业网站都要备案？&lt;/p>&lt;p>　　网站备案与否的问题，举一个例子就好比你有一个苹果你是觉得削皮切成块吃，还是直接吃更好呢？因此多给备案留一点时间走正规流程是很有必要的。&lt;/p>&lt;p>　　2.备案的好处？&lt;/p>&lt;p>　　关于备案好处，从网站体验角度和营销转化角度加以解析。&lt;/p>&lt;p>　　（1）网站在国内备案选择的服务器与机房都是在国内，无论哪种情况打开速度都是要比不备案在国外空间要快许多。&lt;/p>&lt;p>　　（2）品牌性-如果网站是招商加盟性网站或者大品牌性网站，客户在与你合作肯定会多角度考虑，如果你的网站连个备案都没有那么客户是否要去思考你对待项目的长期性呢？&lt;/p>&lt;p>　　（3）个人网站必须要有备案才能上百度联盟、360联盟等广告平台。&lt;/p>&lt;p>　　（4）企业完整申请支付宝、银联等在线支付接口时，网站必须要备案号。（注意：经营性网站需要经营性备案。）&lt;/p>&lt;p>　　3.备案与不备案的区别？&lt;/p>&lt;p>　　目前在中国大陆的企业网站、个人网站，（只要你的服务器机房在中国大陆）不管什么网站都是一样，都要求备案，这个备案是指工信部要求，（工信部的网站上大家可以自行去查询相关的法律法规）各省通讯管局审核，然后下发一个备案号，网站的域名（也就是通常意义上的www.你的名称.com类似的网址）才可以接入互联网访问，否则是不可以访问你的网站的。那么这个备案呢，工信部是为了预防网站出现违法等相关问题的时候可以直接找到你网站的负责人。&lt;/p>&lt;p>　　4.备案号是什么呢？&lt;/p>&lt;p>　　所谓的备案号就是网站底部的一个“&lt;span style="text-align: center">豫ICP备16031090号-1&lt;/span>”这样一个文字，大型网站的底部都有。&lt;/p>&lt;p>　　5、如何查到网站是否备案了？&lt;/p>&lt;p>　　很简单；到工信部的网站上去查询www.miibeian.gov.cn，在这个网站首页的右下角可以点击备案查询，然后在打开的页面输入你的域名、或者网址、或者公司备案名称即可查询到。&lt;/p>&lt;p>　　但是由于这个网站系统不怎么好，经常会有查不到的现象，所以：需要你耐心的多输入几次，或者多换几次查询的方式进行。&lt;/p>&lt;p>　　6、备案需要多久？&lt;/p>&lt;p>　　基本上是20个工作日，这个每个地方都不一定，目前：上海3个工作日左右，其他地方请具体咨询您的服务器空间商，一般最长不会超过20个工作日。&lt;/p>&lt;p>　　二、备案都有哪些种类&lt;/p>&lt;p>　　1、个人为主体备案&lt;/p>&lt;p>　　目前个人为主体全国大致要求是不得超过4个网站。&lt;/p>&lt;p>　　2、企业为主体备案&lt;/p>&lt;p>　　目前企业备案大致要求不得超过40个网站，超过后，需要写网站建设计划书。&lt;/p>&lt;p>　　三、备案需要哪些资料？&lt;/p>&lt;p>　　目前每个省要求都不一样，具体可以咨询一下你网站建设服务商的要求，以下内容大致参考：&lt;/p>&lt;p>　　1、个人为主体备案：&lt;/p>&lt;p>　　个人为主体备案资料比较简单：&lt;/p>&lt;p>　　一般需要身份证正反面拍照或者扫描原件图片一张、真实性核验单一张、去服务商指定拍照地点（带服务商指定背景幕布照片）个人真实拍照一张，必须要求去拍照。&lt;/p>&lt;p>　　2、企业为主体备案：&lt;/p>&lt;p>　　企业为主体备案所需要的资料比较多：&lt;/p>&lt;p>　　企业营业执照正本拍照或扫描图片一张&lt;/p>&lt;p>　　企业法人身份证正反面拍照一张&lt;/p></description></item><item><title>本站上线啦(二)</title><link>https://pangyd.com/post/2/</link><pubDate>Sat, 31 Dec 2016 10:43:38 +0800</pubDate><guid>https://pangyd.com/post/2/</guid><description>&lt;p>看到这个标题有人就说了，你一个小博客，上线就上线了，还“本站上线啦(二)”。在这里我想解释一下，由于内心的极度迫不及待，急于让博客上线，上一篇“本站上线了！”其实没有写完，只写了一部分，还有很多东西没有分享出来。&lt;/p>
&lt;p>其实现在上线的博客并不是我心里想的博客上线之后的样子，当前的博客功能还有很多地方不完善，大多都是功能上的，后台的居多，前台主要是一些细节和用户体验上的不足。比如分页，要做到无限加载，现在只做到了普通分页。&lt;/p>
&lt;p>在本站的首页会看到三个块儿，其中一个是“工匠精神”，精益求精，注重细节，追求完美和极致，不惜花费时间精力，孜孜不倦，反复改进产品，把 99% 提高到 99.99%。&lt;/p>
&lt;p>其实每个人都有一颗追求完美的心，只是追求的程度不同，所以达到的结果也大不相同。但是，每个人对自己的产品或者自己用的产品，肯定会无比的上心。就好比女人出门化妆一样，不能有一点瑕疵。&lt;/p>
&lt;p>搭建博客之初我满怀工匠精神准备将本站做到自己满意才会上线的，可是后来我发现，做到自己满意很难。一个功能或者一个页面在没有做出来之前，你在心里会给自己画个杠杠，想着做成什么什么样就满意了，当这个功能真做出来，你又会发现新的不满意的地方。&lt;/p>
&lt;p>其实追求完美也是需要过程的，万事从无到有，从小到大，从粗糙简陋到极致完美，都需要经历或长或短的过程。庞大如 BAT，他们的系统也是一步步升级迭代出来的，并不是开发出来就是现在这个样子，而是经过无数用户反馈、无数次迭代才成型的。&lt;/p>
&lt;p>经过这些思考，我决定，博客完成基本功能就上线。之后的小细节、新功能都一步步地改善，迭代升级。所以，大家就看到博客现在的样子。&lt;/p>
&lt;p>当然了，博客最主要的还是内容。没有内容做为支撑，再好的用户体验也没用。所以，之后我会发布自己遇到的各种坑，以及爬坑过程，以及好的东西、我认为有用的东西，给大家分享。多多指教！！！&lt;/p></description></item><item><title>本站上线了！</title><link>https://pangyd.com/post/1/</link><pubDate>Thu, 29 Dec 2016 13:49:08 +0800</pubDate><guid>https://pangyd.com/post/1/</guid><description>&lt;p>今年(2016年)年初就打算做一个个人博客了，在年初时候想着才年初，今年还有很长时间，所以就没有着急，一直拖着，这一拖就是半年。&lt;/p>
&lt;p>在五六月分的时候，想着这都半年过去了，博客的事情该提上日程了。于是，我查了想要的域名，看了看服务器，发现阿里云的服务器还是挺贵的。然后说，先做程序(PHP程序猿一只，打算自己开发 CMS)，想着做程序还是要花不少时间的，就这样又拖了两三个月。&lt;/p>
&lt;p>直到九月份中下旬的时候，突然觉得，这再不开工就没时间了呀，因为白天要上班，只能晚上和周末时候有时间来做这个。终于在那一天，就是那一天，我上午选了域名，下午就买了服务器。&lt;/p>
&lt;p>买了域名服务器，域名备案，之后我几乎每天晚上加班两小时攻城(写程序)。到现在，终于告一段落了。&lt;/p>
&lt;p>有时候，做一件事情最开始时候就不能拖延，开始拖延，后面就更拖延，到最后不能在计划的时间内完成。&lt;/p>
&lt;p>总之，不管经历了什么，遇到了什么问题，现在，&lt;strong>本站上线了&lt;/strong>。在开发过程中也遇到了之前没想到的各种小问题，不能说历经磨难，也算小有坎坷。至于开发过程用遇到的各种问题，在之后的文章里再做分享。之后本站的 CMS 也会做分享，希望各位大神多多指教！&lt;/p></description></item></channel></rss>