React 整洁代码最佳实践

原文:Clean Code vs. Dirty Code: React Best Practices

作者:Donavon West

本文主要介绍了适用于现代 React 软件开发的整洁代码实践,顺便谈谈 ES6/ES2015 带来的一些好用的“语法糖”。

什么是整洁代码,为什么要在乎?

整洁代码代表的是一种一致的编码风格,目的是让代码更易于编写,阅读和维护。通常情况下,开发者在解决问题的时候,一旦问题解决就发起一个 Pull Request(译注:合并请求,在 Gitlab 上叫 Merge Request)。但我认为,这时候工作并没有真正完成,我们不能仅仅满足于代码可以工作。

这时候其实就是整理代码的最好时机,可以通过删除死代码(僵尸代码),重构以及删除注释掉的代码,来保持代码的可维护性。不妨问问自己,“从现在开始再过六个月,其他人还能理解这些代码吗?”简而言之,对于自己编写的代码,你应该保证能很自豪地拿给别人看。

至于为什么要在乎这点?因为我们常说一个优秀的开发者大都比较”懒“。在遇到需要重复做某些事情的情况下,他们会去找到一个自动化(或更好的)解决方案来完成这些任务。

整洁代码能够通过“味道测试”

整洁代码应该可以通过“味道测试”。什么意思呢?我们在看代码的时候,包括我们自己写的或或是别人的,会说:“这里不太对劲。”如果感觉不对,那可能就真的是有问题的。如果你觉得你正在试图把一个方形钉子装进一个圆形的洞里,那么就暂停一下,然后休息一下。多次尝试之后,你会找到一个更好的解决方案。

整洁代码是符合 DRY 原则的

DRY 是一个缩略词,意思是“不要重复自己”(Don’t Repeat Yourself)。如果发现多个地方在做同样的事情,那么这时候就应该合并重复代码。如果在代码中看到了模式,那么表明需要实行 DRY。

// Dirty
const MyComponent = () => (
  
);
// Clean
const MyOtherComponent = ({ type }) => (
  
);
const MyComponent = () => (
  
);

有时候,比如在上面的例子中,实行 DRY 原则反而可能会增加代码量。但是,DRY 通常也能够提高代码的可维护性。

注意,很容易陷入过分使用 DRY 原则的陷阱,应该学会适可而止。

整洁代码是可预测和可测试的

编写单元测试不仅仅只是一个好想法,而且应该是强制性的。不然,怎么能确保新功能不会在其他地方引起 Bug 呢?

许多 React 开发人员选择 Jest 作为一个零配置测试运行器,然后生成代码覆盖率报告。如果对测试前后对比可视化感兴趣,请查看美国运通的 Jest Image snanshot。

整洁代码是自注释的

以前发生过这种情况吗?你写了一些代码,并且包含详细的注释。后来你发现一个 bug,于是回去修改代码。但是,你有没有改变注释来体现新的逻辑?也许会,也许不会。下一个看你代码的人可能因为注意到这些注释而掉进一个陷阱。

注释只是为了解释复杂的想法,也就是说,不要对显而易见的代码进行注释。同时,更少的注释也减少了视觉上的干扰。

// Dirty
const fetchUser = (id) => (
  fetch(buildUri`/users/${id}`) // Get User DTO record from REST API
    .then(convertFormat) // Convert to snakeCase
    .then(validateUser) // Make sure the the user is valid
);

在整洁代码的版本中,我们对一些函数进行重命名,以便更好地描述它们的功能,从而消除注释的必要性,减少视觉干扰。并且避免后续因代码与注释不匹配导致的混淆。

// Clean
const fetchUser = (id) => (
  fetch(buildUri`/users/${id}`)
    .then(snakeToCamelCase)
    .then(validateUser)
);

命名

在我之前的文章 将函数作为子组件是一种反模式,强调了命名的重要性。每个开发者都应该认真考虑变量名,函数名,甚至是文件名。

这里列举一下命名原则:

  • 布尔变量或返回布尔值的函数应该以“is”,“has”或“should”开头。

    // Dirty
    const done = current >= goal;
    // Clean
    const isComplete = current >= goal;
  • 函数命名应该体现做了什么,而不是是怎样做的。换言之,不要在命名中体现出实现细节。假如有天出现变化,就不需要因此而重构引用该函数的代码。比如,今天可能会从 REST API 加载配置,但是可能明天就会将其直接写入到 JavaScript 中。

    // Dirty
    const loadConfigFromServer = () => {
      ...
    };
    // Clean
    const loadConfig = () => {
      ...
    };

整洁代码遵循成熟的设计模式和最佳实践

计算机已经存在很长一段时间了。多年以来,程序员通过解决某些特定问题,发现了一些固有套路,被称为设计模式。换言之,有些算法已经被证明是可以工作的,所以应该站在前人的肩膀上,避免犯同样的错误。

那么,什么是最佳实践,与设计模式类似,但是适用范围更广,不仅仅针对编码算法。比如,“应该对代码进行静态检查”或者“当编写一个库时,应该将 React 作为 peerDependency”,这些都可以称为最佳实践。

构建 React 应用程序时,应该遵循以下最佳实践:

  • 使用小函数,每个函数具备单一功能,即所谓的单一职责原则(Single responsibility principle)。确保每个函数都能完成一项工作,并做得很好。这样就能将复杂的组件分解成许多较小的组件。同时,将具备更好的可测试性。
  • 小心抽象泄露(leaky abstractions)。换言之,不要强迫消费方去了解内部代码实现细节。
  • 遵循严格的代码检查规则。这将有助于编写整洁,一致的代码。

整洁代码不需要花长时间来编写

总会听到这样的说法:编写整洁代码会降低生产力。简直是在胡说八道。是的,可能刚开始需要放慢速度,但最终会随着编写更少的代码而节奏加快。

而且,不要小看代码评审导致的重写重构,以及修复问题花费的时间。如果把代码分解成小的模块,每个模块都是单一职责,那么很可能以后再也不用去碰大多数模块了。时间就省下来了,也就是说 “write it and forget it”。

槽糕代码与整洁代码的实例

使用 DRY 原则

看看下面的代码示例。如上所述,从你的显示器退后一步,发现什么模式了吗?注意 Thingie 组件与 ThingieWithTitle 组件除了 Title 组件几乎完全相同,这是实行 DRY 原则的最佳情形。

// Dirty
import Title from './Title';

export const Thingie = ({ description }) => (
  
); export const ThingieWithTitle = ({ title, description }) => (
<div class="description-wrapper"> <Description value={description} /> </div> </div> );</code></pre> <p>在这里,我们将 <code>children</code> 传递给 <code>Thingie</code>。然后创建 <code>ThingieWithTitle</code>,这个组件包含 <code>Thingie</code>,并将 <code>Title</code> 作为其子组件传给 <code>Thingie</code>。</p> <pre><code class="js">// Clean import Title from './Title'; export const Thingie = ({ description, children }) => ( <div class="thingie"> {children} <div class="description-wrapper"> <Description value={description} /> </div> </div> ); export const ThingieWithTitle = ({ title, ...others }) => ( <Thingie {...others}> <Title value={title} /> </Thingie> );</code></pre> <h3>默认值</h3> <p>看看下面的代码。使用逻辑或将 <code>className</code> 的默认值设置成 “icon-large”,看起来像是上个世纪的人才会写的代码。</p> <pre><code class="js">// Dirty const Icon = ({ className, onClick }) => { const additionalClasses = className || 'icon-large'; return ( <span className={`icon-hover ${additionalClasses}`} onClick={onClick}> </span> ); };</code></pre> <p>这里我们使用 ES6 的默认语法来替换 <code>undefined</code> 时的值,而且还能使用 ES6 的箭头函数表达式写成单一语句形式,从而去除对 <code>return</code> 的依赖。</p> <pre><code class="js">// Clean const Icon = ({ className = 'icon-large', onClick }) => ( <span className={`icon-hover ${className}`} onClick={onClick} /> );</code></pre> <p>在下面这个更整洁的版本中,使用 React 中的 API 来设置默认值。</p> <pre><code class="js">// Cleaner const Icon = ({ className, onClick }) => ( <span className={`icon-hover ${className}`} onClick={onClick} /> ); Icon.defaultProps = { className: 'icon-large', };</code></pre> <p>为什么这样显得更加整洁?而且它真的会更好吗?三个版本不是都在做同样的事情吗?某种意义上来说,是对的。让 React 设置 prop 默认值的好处是,可以产生更高效的代码,而且在基于 <code>Class</code> 的生命周期组件中允许通过 <code>propTypes</code> 检查默认值。还有一个优点是:将默认逻辑从组件本身抽离出来。</p> <p>例如,你可以执行以下操作,将所有默认属性放到一个地方。当然,并不是建议你这样做,只是说具有这样的灵活性。</p> <pre><code class="js">import defaultProps from './defaultProps'; // ... Icon.defaultProps = defaultProps.Icon;</code></pre> <h3>从渲染分离有状态的部分</h3> <p>将有状态的数据加载逻辑与渲染逻辑混合可能增加组件复杂性。更好的方式是,写一个负责完成数据加载的有状态的容器组件,然后编写另一个负责显示数据的组件。这被称为 容器模式。</p> <p>在下面的示例中,用户数据加载和显示功能放在一个组件中。</p> <pre><code class="js">// Dirty class User extends Component { state = { loading: true }; render() { const { loading, user } = this.state; return loading ? <div>Loading...</div> : <div> <div> First name: {user.firstName} </div> <div> First name: {user.lastName} </div> ... </div>; } componentDidMount() { fetchUser(this.props.id) .then((user) => { this.setState({ loading: false, user })}) } }</code></pre> <p>在整洁版本中,加载数据和显示数据已经分离。这不仅使代码更容易理解,而且能减少测试的工作量,因为可以独立测试每个部分。而且由于 <code>RenderUser</code> 是一个无状态组件,所以结果是可预测的。</p> <pre><code class="js">// Clean import RenderUser from './RenderUser'; class User extends Component { state = { loading: true }; render() { const { loading, user } = this.state; return loading ? <Loading /> : <RenderUser user={user} />; } componentDidMount() { fetchUser(this.props.id) .then(user => { this.setState({ loading: false, user })}) } }</code></pre> <h3>使用无状态组件</h3> <p>React v0.14.0 中引入了无状态函数组件(SFC),被简化成纯渲染组件,但有些开发者还在使用过去的方式。例如,以下组件就应该转换为 SFC。</p> <pre><code class="js">// Dirty class TableRowWrapper extends Component { render() { return ( <tr> {this.props.children} </tr> ); } }</code></pre> <p>整洁版本清除了很多可能导致干扰的信息。通过 React 核心的优化,使用无状态组件将占用更少的内存,因为没有创建 Component 实例。</p> <pre><code class="js">// Clean const TableRowWrapper = ({ children }) => ( <tr> {children} </tr> ); </code></pre> <h3>剩余/扩展属性(rest/spread)</h3> <p>大约在一年前,我还推荐大家多用 <code>Object.assign</code>。但时代变化很快,在 ES2016/ES7 中引入新特性 rest/spread。</p> <p>比如这样一种场景,当传递给一些 props 给一个组件,只希望在组件本身使用 <code>className</code>,但是需要将其他所有 props 传递到子组件。这时,你可能会这样做:</p> <pre><code class="js">// Dirty const MyComponent = (props) => { const others = Object.assign({}, props); delete others.className; return ( <div className={props.className}> {React.createElement(MyOtherComponent, others)} </div> ); }; </code></pre> <p>这不是一个非常优雅的解决方案。但是使用 rest/spread,就能轻而易举地实现,</p> <pre><code class="js">// Clean const MyComponent = ({ className, ...others }) => ( <div className={className}> <MyOtherComponent {...others} /> </div> );</code></pre> <p>我们将剩余属性展开并作为新的 props 传递给 <code>MyOtherComponent</code> 组件。</p> <h3>合理使用解构</h3> <p>ES6 引入 解构(destructuring) 的概念,这是一个非常棒的特性,用类似对象或数组字面量的语法获取一个对象的属性或一个数组的元素。</p> <h4>对象解构</h4> <p>在这个例子中,<code>componentWillReceiveProps</code> 组件接收 <code>newProps</code> 参数,然后将其 <code>active</code> 属性设置为新的 <code>state.active</code>。</p> <pre><code class="js">// Dirty componentWillReceiveProps(newProps) { this.setState({ active: newProps.active }); }</code></pre> <p>在整洁版本中,我们解构 <code>newProps </code>成 <code>active</code>。这样我们不仅不需要引用 <code>newProps.active</code>,而且也可以使用 ES6 的简短属性特性来调用 <code>setState</code>。</p> <pre><code>// Clean componentWillReceiveProps({ active }) { this.setState({ active }); } </code></pre> <h4>数组解构</h4> <p>一个经常被忽视的 ES6 特性是数组解构。以下面的代码为例,它获取 <code>locale</code> 的值,比如“en-US”,并将其分成 <code>language</code>(en)和 <code>country</code>(US)。</p> <pre><code class="js">// Dirty const splitLocale = locale.split('-'); const language = splitLocale[0]; const country = splitLocale[1]; </code></pre> <p>在整洁版本,使用 ES6 的数组解构特性可以自动完成上述过程:</p> <pre><code class="js">// Clean const [language, country] = locale.split('-'); </code></pre> <h2>所以结论是</h2> <p>希望这篇文章能有助于你看到编写整洁代码的好处,甚至可以直接使用这里介绍的一些代码示例。一旦你习惯编写整洁代码,将很快就会体会到 “write it and forget it” 的生活方式。</p> </div> </div> </div> </div> </div> </div> <!--PC和WAP自适应版--> <div id="SOHUCS" sid="1343943075080253440"></div> <script type="text/javascript" src="/views/front/js/chanyan.js"></script> <!-- 文章页-底部 动态广告位 --> <div class="youdao-fixed-ad" id="detail_ad_bottom"></div> </div> <div class="col-md-3"> <div class="row" id="ad"> <!-- 文章页-右侧1 动态广告位 --> <div id="right-1" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad"> <div class="youdao-fixed-ad" id="detail_ad_1"> </div> </div> <!-- 文章页-右侧2 动态广告位 --> <div id="right-2" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad"> <div class="youdao-fixed-ad" id="detail_ad_2"></div> </div> <!-- 文章页-右侧3 动态广告位 --> <div id="right-3" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad"> <div class="youdao-fixed-ad" id="detail_ad_3"></div> </div> </div> </div> </div> </div> </div> <div class="container"> <h4 class="pt20 mb15 mt0 border-top">你可能感兴趣的:(设计模式,测试,javascript)</h4> <div id="paradigm-article-related"> <div class="recommend-post mb30"> <ul class="widget-links"> <li><a href="/article/1950232820773351424.htm" title="移动端城市区县二级联动选择功能实现包" target="_blank">移动端城市区县二级联动选择功能实现包</a> <span class="text-muted">good2know</span> <div>本文还有配套的精品资源,点击获取简介:本项目是一套为移动端设计的jQuery实现方案,用于简化用户在选择城市和区县时的流程。它包括所有必需文件:HTML、JavaScript、CSS及图片资源。通过动态更新下拉菜单选项,实现城市到区县的联动效果,支持数据异步加载。开发者可以轻松集成此功能到移动网站或应用,并可基于需求进行扩展和优化。1.jQuery移动端解决方案概述jQuery技术简介jQuery</div> </li> <li><a href="/article/1950230114205757440.htm" title="现在发挥你的优势" target="_blank">现在发挥你的优势</a> <span class="text-muted">爱生活的佑嘉</span> <div>来和我做咨询的一些朋友,涉及到定位的,都会说,我不知道我的优势是什么,你能不能帮我看看?还有一些朋友,喜欢做各种测试来了解自己,测试过后,然并卵。今天,我想来聊聊优势,如何能了解自己的优势是什么。首先,我们要知道,如果要成为“不一般”的人,我们所做的事情,就要基于自身的优势。我做管理者十多年,看到每个员工都有不同的特长,有的擅长数字,有的擅长人际,有的擅长写作。这些知道自己优势并且在这方面刻意练习</div> </li> <li><a href="/article/1950225381961297920.htm" title="SpringMVC的执行流程" target="_blank">SpringMVC的执行流程</a> <span class="text-muted"></span> <div>1、什么是MVCMVC是一种设计模式。MVC的原理图如下所示M-Model模型(完成业务逻辑:有javaBean构成,service+dao+entity)V-View视图(做界面的展示jsp,html……)C-Controller控制器(接收请求—>调用模型—>根据结果派发页面2、SpringMVC是什么SpringMVC是一个MVC的开源框架,SpringMVC=Struts2+Spring,</div> </li> <li><a href="/article/1950223497875746816.htm" title="最新阿里四面面试真题46道:面试技巧+核心问题+面试心得" target="_blank">最新阿里四面面试真题46道:面试技巧+核心问题+面试心得</a> <span class="text-muted">风平浪静如码</span> <div>前言做技术的有一种资历,叫做通过了阿里的面试。这些阿里Java相关问题,都是之前通过不断优秀人才的铺垫总结的,先自己弄懂了再去阿里面试,不然就是去丢脸,被虐。希望对大家帮助,祝面试成功,有个更好的职业规划。一,阿里常见技术面1、微信红包怎么实现。2、海量数据分析。3、测试职位问的线程安全和非线程安全。4、HTTP2.0、thrift。5、面试电话沟通可能先让自我介绍。6、分布式事务一致性。7、ni</div> </li> <li><a href="/article/1950212284320116736.htm" title="漫步,跳出藩篱" target="_blank">漫步,跳出藩篱</a> <span class="text-muted">张巧金沙</span> <div>最近的教学,倍感不爽。一为这国庆之假,把这课上得支离破碎的。放假前,上了四天课,但我却只上了三天,9月30日,我工作室在搞活动,全天的活动,课当然未能上。10月8日学生回校,上了两天课,学生又放回家了。就觉得学生刚有点状态,又回去逍遥去了。感觉吧,教学内容也不敢大胆甩开膀子去教学,所以呀,这教学内容还真上不走,而且学生学下来效果特差。这不,国庆放假前的一个周,测试了两次,均为第一单元,是自考试以来</div> </li> <li><a href="/article/1950209368356089856.htm" title="AI模型训练中过拟合和欠拟合的区别是什么?" target="_blank">AI模型训练中过拟合和欠拟合的区别是什么?</a> <span class="text-muted">workflower</span> <a class="tag" taget="_blank" href="/search/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/1.htm">人工智能</a><a class="tag" taget="_blank" href="/search/%E7%AE%97%E6%B3%95/1.htm">算法</a><a class="tag" taget="_blank" href="/search/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/1.htm">人工智能</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90/1.htm">数据分析</a> <div>在AI模型训练中,过拟合和欠拟合是两种常见的模型性能问题,核心区别在于模型对数据的学习程度和泛化能力:欠拟合(Underfitting)-定义:模型未能充分学习到数据中的规律,对训练数据的拟合程度较差,在训练集和测试集上的表现都不好(如准确率低、损失值高)。-原因:-模型结构过于简单(如用线性模型解决非线性问题);-训练数据量不足或特征信息不充分;-训练时间太短,模型尚未学到有效模式。-表现:训练</div> </li> <li><a href="/article/1950207097023033344.htm" title="Pktgen-DPDK:开源网络测试工具的深度解析与应用" target="_blank">Pktgen-DPDK:开源网络测试工具的深度解析与应用</a> <span class="text-muted">艾古力斯</span> <div>本文还有配套的精品资源,点击获取简介:Pktgen-DPDK是基于DPDK的高性能流量生成工具,适用于网络性能测试、硬件验证及协议栈开发。它支持多种网络协议,能够模拟高吞吐量的数据包发送。本项目通过利用DPDK的高速数据包处理能力,允许用户自定义数据包内容,并实现高效的数据包管理与传输。文章将指导如何安装DPDK、编译Pktgen、配置工具以及使用方法,最终帮助开发者和网络管理员深入理解并优化网络</div> </li> <li><a href="/article/1950206309123026944.htm" title="语文教学反思 ——一单元测试" target="_blank">语文教学反思 ——一单元测试</a> <span class="text-muted">一抹_绿茶香</span> <div>我喜欢上语文课,现在最开心的时刻也就是课上那45分钟了。它可以让我和孩子们骑上骏马驰骋在知识的草原上,可以让我们乘着巨轮在书籍的海洋里任意航行……周三举行了一单元测试,今晚一单元的所有内容暂时告一段落。对于这单元我有如下思考:本单元的主题词是“读书”,几篇课文都是围绕着读书来编排的。里面有讲读书乐趣的,讲读书方法的,还有孩子们第一次接触的访谈录等。微笑班级从一年级下学期就开始阅读“闲书”,所以教学</div> </li> <li><a href="/article/1950205711409541120.htm" title="selenium特殊场景处理" target="_blank">selenium特殊场景处理</a> <span class="text-muted">Monica_ll</span> <a class="tag" taget="_blank" href="/search/Selenium/1.htm">Selenium</a><a class="tag" taget="_blank" href="/search/selenium/1.htm">selenium</a><a class="tag" taget="_blank" href="/search/chrome/1.htm">chrome</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a> <div>文章目录前言一、多窗口处理二、浏览器弹窗处理包含alert、confirm、prompt三、鼠标和键盘事件处理前言在使用selenium操作浏览器的过程中可能需要借助键盘和鼠标功能完成一些操作,或者操作弹窗处理,本文主要是整理自己工作过程中使用过的一些方法一、多窗口处理在实际测试过程中经常会有通过点击或者连接打开新的窗口,这种情况下就需要切换webDriver到对应浏览器对象才能操作新窗口的元素。</div> </li> <li><a href="/article/1950199910724857856.htm" title="机器学习必备数学与编程指南:从入门到精通" target="_blank">机器学习必备数学与编程指南:从入门到精通</a> <span class="text-muted">a小胡哦</span> <a class="tag" taget="_blank" href="/search/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%E5%9F%BA%E7%A1%80/1.htm">机器学习基础</a><a class="tag" taget="_blank" href="/search/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0/1.htm">机器学习</a><a class="tag" taget="_blank" href="/search/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/1.htm">人工智能</a> <div>一、机器学习核心数学基础1.线性代数(神经网络的基础)必须掌握:矩阵运算(乘法、转置、逆)向量空间与线性变换特征值分解与奇异值分解(SVD)为什么重要:神经网络本质就是矩阵运算学习技巧:用NumPy实际操作矩阵运算2.概率与统计(模型评估的关键)核心概念:条件概率与贝叶斯定理概率分布(正态、泊松、伯努利)假设检验与p值应用场景:朴素贝叶斯、A/B测试3.微积分(优化算法的基础)重点掌握:导数与偏导</div> </li> <li><a href="/article/1950194868756213760.htm" title="程序员必备:10 个提升代码质量的工具" target="_blank">程序员必备:10 个提升代码质量的工具</a> <span class="text-muted">大力出奇迹985</span> <a class="tag" taget="_blank" href="/search/%E5%AE%A0%E7%89%A9/1.htm">宠物</a> <div>在软件开发过程中,代码质量对项目的成功起着决定性作用。高质量的代码不仅易于维护和扩展,还能有效降低成本并提升可靠性。本文精心挑选了10个程序员必备工具,助力提升代码质量。这些工具涵盖代码格式化、静态分析、代码审查、测试、性能优化、安全扫描、版本控制、依赖管理、代码生成以及文档生成等多个关键领域。通过使用它们,开发者能够高效地发现并解决代码中的潜在问题,遵循最佳实践,提升代码的可读性、可维护性与安全</div> </li> <li><a href="/article/1950194742100815872.htm" title="用代码生成艺术字:设计个性化海报的秘密" target="_blank">用代码生成艺术字:设计个性化海报的秘密</a> <span class="text-muted"></span> <div>本文围绕“用代码生成艺术字:设计个性化海报的秘密”展开,先概述代码生成艺术字在海报设计中的独特价值,接着介绍常用的代码工具(如HTML、CSS、JavaScript等),详细阐述从构思到实现的完整流程,包括字体样式设计、动态效果添加等,还分享了提升艺术字质感的技巧及实际案例。最后总结代码生成艺术字的优势,为设计师提供打造个性化海报的实用指南,助力提升海报设计的独特性与吸引力,符合搜索引擎SEO标准</div> </li> <li><a href="/article/1950194728943284224.htm" title="java实习生40多天有感" target="_blank">java实习生40多天有感</a> <span class="text-muted">别拿爱情当饭吃</span> <div>从5月15日开始,我开始第一步步入社会,我今年大三,在一家上市互联网公司做一名实习生,主要做java后端开发。开始的时候,觉得公司的环境挺不错的,不过因为公司在CBD,所以隔壁的午饭和晚饭都要20+RMB,而且还吃不饱,这让我感觉挺郁闷的。一到下午,我就会犯困(因为饿)。因此,我又不得不买一些干粮在公司屯着。关于技术,有一个比较大的项目在需求调研当中,我们做实习生,就是辅助项目经理,测试功能,并且</div> </li> <li><a href="/article/1950191587556388864.htm" title="C#中的设计模式:构建更加优雅的代码" target="_blank">C#中的设计模式:构建更加优雅的代码</a> <span class="text-muted">Envyᥫᩣᩚ</span> <a class="tag" taget="_blank" href="/search/c%23/1.htm">c#</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a> <div>C#在面向对象编程(OOP)方面的强大支持,我们可以探讨“C#中的设计模式”。这不仅有助于理解如何更好地组织代码,还能提高代码的可维护性和可扩展性。引言设计模式是软件工程中经过实践验证的解决方案模板,它们提供了一种标准化的方法来解决常见的开发问题。对于使用C#进行开发的程序员来说,理解和应用这些模式可以帮助创建结构良好、易于维护和扩展的应用程序。本文将介绍几种常用的设计模式,并展示如何用C#实现它</div> </li> <li><a href="/article/1950182762610749440.htm" title="《天才在左,疯子在右——心理疾病漫谈》|你焦虑了嘛?" target="_blank">《天才在左,疯子在右——心理疾病漫谈》|你焦虑了嘛?</a> <span class="text-muted">霞姝儿</span> <div>《天才在左,疯子在右——心理疾病漫谈》这本书的作者是宁安宁,2015年12月在哈尔冰出版社出版。ISBN:9787548423676.我花了5个小时40分钟看完的。这本书中很多关于行为和心理活动情况的分析与案例解析都很透彻。书中针对每个心理障碍都会有是非题供你来测试,有解析心理障碍出现的原因,有问题的症状表现形式的阐述,有类似问题的案例解析,还有解决方案的描写。看完之后,你可以对自己心理上及行为上</div> </li> <li><a href="/article/1950175200347746304.htm" title="深入剖析 boost::unique_lock<boost::mutex>" target="_blank">深入剖析 boost::unique_lock<boost::mutex></a> <span class="text-muted">程序员乐逍遥</span> <a class="tag" taget="_blank" href="/search/C%2B%2B/1.htm">C++</a><a class="tag" taget="_blank" href="/search/Boost%E5%BA%93/1.htm">Boost库</a><a class="tag" taget="_blank" href="/search/C%2FC%2B%2B%E5%A4%9A%E7%BA%BF%E7%A8%8B%E7%BC%96%E7%A8%8B%E4%B8%93%E9%A2%98/1.htm">C/C++多线程编程专题</a><a class="tag" taget="_blank" href="/search/C%2B%2B/1.htm">C++</a><a class="tag" taget="_blank" href="/search/boost/1.htm">boost</a><a class="tag" taget="_blank" href="/search/%E7%BA%BF%E7%A8%8B/1.htm">线程</a><a class="tag" taget="_blank" href="/search/%E9%94%81/1.htm">锁</a> <div>在高并发的C++程序中,线程安全是永恒的主题。而boost::unique_lock作为Boost.Thread库中的核心组件,为开发者提供了强大、灵活且异常安全的互斥量管理机制。它不仅是RAII(ResourceAcquisitionIsInitialization)设计模式的典范,更是实现复杂线程同步逻辑的基石。一、从lock_guard的说起在介绍unique_lock之前,我们先回顾其“简</div> </li> <li><a href="/article/1950164483057971200.htm" title="14.tornado操作之应用Websocket协议实现聊天室功能" target="_blank">14.tornado操作之应用Websocket协议实现聊天室功能</a> <span class="text-muted">孤寒者</span> <a class="tag" taget="_blank" href="/search/Tornado%E6%A1%86%E6%9E%B6%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%AE%9E%E6%88%98/1.htm">Tornado框架从入门到实战</a><a class="tag" taget="_blank" href="/search/websocket/1.htm">websocket</a><a class="tag" taget="_blank" href="/search/tornado/1.htm">tornado</a><a class="tag" taget="_blank" href="/search/%E8%81%8A%E5%A4%A9%E5%AE%A4%E5%8A%9F%E8%83%BD%E5%AE%9E%E7%8E%B0/1.htm">聊天室功能实现</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a> <div>目录:每篇前言:1.什么是WebSocket(1)定义(2)优点(3)和HTTP对比(4)适用场景2.WebSocket关键方法3.本tornado项目中使用WebSocket(1)准备一个聊天室的页面:第一步:编写视图:第二步:编写接口:(app.py中加入以下接口!)第三步:编写前端页面:测试接口——响应OK!(2)使用WebSocket:(3)聊天室的聊天功能的最终实现:第一步:战前准备第二</div> </li> <li><a href="/article/1950160628047998976.htm" title="网络如何赚钱?用手机怎么赚钱?" target="_blank">网络如何赚钱?用手机怎么赚钱?</a> <span class="text-muted">氧惠_飞智666999</span> <div>网络赚钱不是你以为的那样,不是你想赚就能赚的,你需要一个很好的思路,让自己赚钱起来。今天我就给大家分享下这个方法,教咱们如何用手机操作互联网赚钱,这个非常简单。首先教你们怎样玩手机赚钱。第一步:打开淘宝或者拍拍、拼多多搜索赚钱项目。第二步:在网上搜一个项目或者产品,下载下来进行安装好之后去测试这个软件是否可以进行操作。第三步:进入测试后就点击第一个按钮进行提交就行了。第四步:提交后等待审核就行了。</div> </li> <li><a href="/article/1950150865553780736.htm" title="【数据分析】抓包工具的定义常见类型分类使用场景及注意事项" target="_blank">【数据分析】抓包工具的定义常见类型分类使用场景及注意事项</a> <span class="text-muted"></span> <div>抓包工具的定义常见类型分类使用场景及注意事项-CSDN直播抓包工具的定义常见类型分类使用场景及注意事项抓包工具的定义常见类型分类使用场景及注意事项抓包工具概述抓包工具顾名思义是一种用于捕获并分析网络数据包的软件或硬件工具它能够在数据传输过程中截取并记录网络流量让用户能够深入理解并排查网络问题这类工具的用途广泛从网络安全测试到应用程序调试都离不开抓包工具的帮助在众多的抓包工具中WiresharkFi</div> </li> <li><a href="/article/1950145071722590208.htm" title="常见的接⼝测试⾯试题" target="_blank">常见的接⼝测试⾯试题</a> <span class="text-muted">lifewange</span> <a class="tag" taget="_blank" href="/search/%E6%8E%A5%E5%8F%A3%E6%B5%8B%E8%AF%95-%E5%8A%9F%E8%83%BD%2B%E8%87%AA%E5%8A%A8%E5%8C%96/1.htm">接口测试-功能+自动化</a><a class="tag" taget="_blank" href="/search/%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95/1.htm">单元测试</a> <div>根据⽹络资料,总结了以下⼀些常见的接⼝测试⾯试题:1.为什么要做接⼝测试?在讨论为什么要做接⼝测试之前,我们先稍微了解下接⼝是什么?接⼝可以很不准确的理解成是与资源打交道,这个资源可能是本系统的,也可能是其他系统的。举个例⼦,假如我们在开发1个bug管理系统,该系统需要拿到公司的所有开发和测试⼈员的信息,这样开发和测试⼈员不⽤注册都可以登录进去了,这应该很好理解。那么这些⼈员的信息储存在哪⾥呢?⼀</div> </li> <li><a href="/article/1950144316261330944.htm" title="零基础学习性能测试第八章:高并发-redis缓存架构介绍" target="_blank">零基础学习性能测试第八章:高并发-redis缓存架构介绍</a> <span class="text-muted">试着</span> <a class="tag" taget="_blank" href="/search/%E6%80%A7%E8%83%BD%E6%B5%8B%E8%AF%95/1.htm">性能测试</a><a class="tag" taget="_blank" href="/search/%E7%BC%93%E5%AD%98/1.htm">缓存</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a><a class="tag" taget="_blank" href="/search/redis/1.htm">redis</a><a class="tag" taget="_blank" href="/search/%E6%80%A7%E8%83%BD%E6%B5%8B%E8%AF%95/1.htm">性能测试</a><a class="tag" taget="_blank" href="/search/%E9%9B%B6%E5%9F%BA%E7%A1%80/1.htm">零基础</a> <div>目录一、Redis在高并发中的核心价值二、Redis核心架构模式▶1.缓存穿透防御架构▶2.热点数据多级缓存三、Redis集群高可用方案▶1.RedisCluster分片架构▶2.读写分离方案四、Redis性能压测实战▶1.基准测试工具▶2.关键性能指标五、典型瓶颈分析与优化案例1:缓存雪崩案例2:热Key阻塞六、电商秒杀实战架构七、必须掌握的进阶技巧八、学习路径与工具推荐以下是为零基础学习者设计</div> </li> <li><a href="/article/1950144218282389504.htm" title="为什么学习Web前端一定要掌握JavaScript?" target="_blank">为什么学习Web前端一定要掌握JavaScript?</a> <span class="text-muted">web前端学习指南</span> <div>为什么学习Web前端一定要掌握JavaScript?在前端的世界里,没有什么是JavaScript实现不了的,关于JS有一句话:凡是可以用JavaScript来写的应用,最终都会用JavaScript,JavaScript可运行在所有主要平台的所有主流浏览器上,也可运行在每一个主流操作系统的服务器端上。现如今我们在为网站写任何一个主要功能的时候都需要有懂能够用JavaScript写前端的开发人员。</div> </li> <li><a href="/article/1950141285335625728.htm" title="【测试用例】银行借款业务" target="_blank">【测试用例】银行借款业务</a> <span class="text-muted"></span> <div>一、功能测试:借款申请流程:验证用户能够按照正常流程完成借款申请,包括填写借款金额、选择借款期限、提交必要的申请材料等步骤。验证系统能够正确处理用户提交的借款申请,包括申请信息的完整性和准确性检查。借款额度与期限:验证系统能够根据用户的信用评级和借款政策,正确计算并显示用户的可借款额度和期限范围。测试用户选择不同的借款额度和期限时,系统能否正确计算相关费用和还款计划。利率和费用计算:验证系统能够正</div> </li> <li><a href="/article/1950141285767639040.htm" title="【测试用例】银行授信业务" target="_blank">【测试用例】银行授信业务</a> <span class="text-muted">小邓在Working</span> <a class="tag" taget="_blank" href="/search/%E6%B5%8B%E8%AF%95%E7%94%A8%E4%BE%8B/1.htm">测试用例</a><a class="tag" taget="_blank" href="/search/%E6%B5%8B%E8%AF%95%E7%94%A8%E4%BE%8B/1.htm">测试用例</a><a class="tag" taget="_blank" href="/search/%E5%8A%9F%E8%83%BD%E6%B5%8B%E8%AF%95/1.htm">功能测试</a><a class="tag" taget="_blank" href="/search/%E6%80%A7%E8%83%BD%E6%B5%8B%E8%AF%95/1.htm">性能测试</a><a class="tag" taget="_blank" href="/search/%E5%AE%89%E5%85%A8%E6%B5%8B%E8%AF%95/1.htm">安全测试</a><a class="tag" taget="_blank" href="/search/%E4%BA%A4%E4%BA%92%E6%B5%8B%E8%AF%95/1.htm">交互测试</a><a class="tag" taget="_blank" href="/search/%E4%B8%80%E8%87%B4%E6%80%A7%E6%B5%8B%E8%AF%95/1.htm">一致性测试</a> <div>一、功能测试:授信申请流程:验证客户能正常提交授信申请,并检查信息完整性和准确性。测试申请被拒绝或需要额外信息时的系统反馈。反欺诈与风控系统集成:验证系统能调用反欺诈接口并正确处理返回结果。测试系统调用风控接口获取授信建议和额度管理决策。用户信息校验与九要素验证:验证系统对客户提供的九要素信息进行准确性和一致性校验。测试校验失败时的错误提示和处理逻辑。重复授信检查与处理:验证系统能识别并处理重复授</div> </li> <li><a href="/article/1950141284484182016.htm" title="【测试用例】银行冲正业务" target="_blank">【测试用例】银行冲正业务</a> <span class="text-muted"></span> <div>一、冲正申请阶段冲正原因测试点验证冲正原因的选择是否符合预设的业务规则。验证冲正原因的输入是否支持自由文本,并检查文本长度限制。验证系统是否能够正确保存冲正原因,并在需要时正确显示。冲正金额测试点验证冲正金额的输入格式是否正确(如是否只接受数字、是否有金额上限等)。验证冲正金额与原交易金额的匹配性(如是否一致、是否小于原交易金额等)。验证系统是否能够正确处理冲正金额为0或负数的异常情况。冲正账户信</div> </li> <li><a href="/article/1950141284907806720.htm" title="【测试用例】银行还款业务" target="_blank">【测试用例】银行还款业务</a> <span class="text-muted"></span> <div>一、功能测试:正常还款流程:选择还款账户、输入还款金额、确认还款信息。验证还款账户余额是否足够。验证还款成功后,账户余额、应还金额和还款状态是否更新。逾期还款:验证逾期罚息计算是否正确。验证逾期后的还款流程是否与正常还款有所不同。验证逾期还款后,账户状态和还款记录是否更新。不同还款账户:使用多个不同的还款账户进行还款。验证还款账户变更时,系统能否正确处理。余额不足还款:尝试还款金额大于账户余额的情</div> </li> <li><a href="/article/1950141158143356928.htm" title="【测试用例】借款app" target="_blank">【测试用例】借款app</a> <span class="text-muted">小邓在Working</span> <a class="tag" taget="_blank" href="/search/%E6%B5%8B%E8%AF%95%E7%94%A8%E4%BE%8B/1.htm">测试用例</a><a class="tag" taget="_blank" href="/search/%E6%B5%8B%E8%AF%95%E7%94%A8%E4%BE%8B/1.htm">测试用例</a><a class="tag" taget="_blank" href="/search/%E5%8A%9F%E8%83%BD%E6%B5%8B%E8%AF%95/1.htm">功能测试</a><a class="tag" taget="_blank" href="/search/%E5%AE%89%E5%85%A8%E6%80%A7%E6%B5%8B%E8%AF%95/1.htm">安全性测试</a><a class="tag" taget="_blank" href="/search/%E6%B5%8B%E8%AF%95%E8%A6%86%E7%9B%96%E7%8E%87/1.htm">测试覆盖率</a><a class="tag" taget="_blank" href="/search/%E5%8F%AF%E7%94%A8%E6%80%A7%E6%B5%8B%E8%AF%95/1.htm">可用性测试</a> <div>信贷app借款流程的测试点需要覆盖用户从申请借款到最终放款的整个流程。1.注册与登录注册功能:验证新用户能否成功注册,包括输入有效和无效信息时的反应。登录功能:已注册用户是否能成功登录,包括密码找回和重置功能。安全性:密码强度检查,多次尝试登录失败后的处理(如账户锁定)。2.信息填写与提交借款人信息:验证借款人能否正确输入个人信息(姓名、身份证号、联系方式等)。借款金额与期限:验证用户能否选择借款</div> </li> <li><a href="/article/1950135734396579840.htm" title="国产测试用例管理工具横向评测:DevOps时代如何选择最适合的协作平台?" target="_blank">国产测试用例管理工具横向评测:DevOps时代如何选择最适合的协作平台?</a> <span class="text-muted">不念霉运</span> <a class="tag" taget="_blank" href="/search/%E6%B5%8B%E8%AF%95%E7%94%A8%E4%BE%8B/1.htm">测试用例</a><a class="tag" taget="_blank" href="/search/devops/1.htm">devops</a><a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4/1.htm">运维</a> <div>国产测试用例管理工具横向评测:DevOps时代如何选择最适合的协作平台?在数字化转型浪潮下,软件研发效能已成为企业核心竞争力。作为DevOps流程中的关键环节,测试用例管理工具的选择直接影响着团队的协作效率和产品质量。面对市场上琳琅满目的国产解决方案,研发团队该如何做出明智选择?GiteeTest:为敏捷团队打造的工程化测试管理利器GiteeTest凭借其"工程化"的用例管理理念,在敏捷开发场景中</div> </li> <li><a href="/article/1950133970091962368.htm" title="还款流程设计测试用例" target="_blank">还款流程设计测试用例</a> <span class="text-muted">lifewange</span> <a class="tag" taget="_blank" href="/search/%E6%B5%8B%E8%AF%95%E7%94%A8%E4%BE%8B/1.htm">测试用例</a> <div>设计还款流程的测试用例时,需覆盖正常还款、异常还款、部分还款、提前还款、逾期还款等场景,并验证系统处理、账务核对、通知提醒、风控拦截等功能。以下是详细的测试用例设计思路和示例:一、核心测试维度测试类型关键验证点功能测试还款金额计算、账务更新、状态变更、通知触发异常测试失败还款(余额不足、账户异常)、重复还款、非法操作合规测试利息/违约金计算是否符合监管要求(如年化利率上限)性能测试批量还款时系统并</div> </li> <li><a href="/article/1950132582230323200.htm" title="使用 C# 实现 FTP 上传的方法,包括详细的代码示例和测试代码" target="_blank">使用 C# 实现 FTP 上传的方法,包括详细的代码示例和测试代码</a> <span class="text-muted">zhxup606</span> <a class="tag" taget="_blank" href="/search/%E6%9D%8E%E5%B7%A5%E7%AF%87/1.htm">李工篇</a><a class="tag" taget="_blank" href="/search/C%23%E5%AE%9E%E6%88%98%E6%95%99%E7%A8%8B/1.htm">C#实战教程</a><a class="tag" taget="_blank" href="/search/c%23/1.htm">c#</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a> <div>以下是使用C#实现FTP上传的方法,包括详细的代码示例和测试代码。以下代码使用System.Net.FtpWebRequest实现文件上传,并附带一个简单的测试用例。C#FTP上传方法csharpusingSystem;usingSystem.IO;usingSystem.Net;publicclassFtpClient{//////上传文件到FTP服务器//////FTP服务器地址,例如ftp:</div> </li> <li><a href="/article/110.htm" title="强大的销售团队背后 竟然是大数据分析的身影" target="_blank">强大的销售团队背后 竟然是大数据分析的身影</a> <span class="text-muted">蓝儿唯美</span> <a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90/1.htm">数据分析</a> <div>Mark Roberge是HubSpot的首席财务官,在招聘销售职位时使用了大量数据分析。但是科技并没有挤走直觉。 大家都知道数理学家实际上已经渗透到了各行各业。这些热衷数据的人们通过处理数据理解商业流程的各个方面,以重组弱点,增强优势。 Mark Roberge是美国HubSpot公司的首席财务官,HubSpot公司在构架集客营销现象方面出过一份力——因此他也是一位数理学家。他使用数据分析 </div> </li> <li><a href="/article/237.htm" title="Haproxy+Keepalived高可用双机单活" target="_blank">Haproxy+Keepalived高可用双机单活</a> <span class="text-muted">bylijinnan</span> <a class="tag" taget="_blank" href="/search/%E8%B4%9F%E8%BD%BD%E5%9D%87%E8%A1%A1/1.htm">负载均衡</a><a class="tag" taget="_blank" href="/search/keepalived/1.htm">keepalived</a><a class="tag" taget="_blank" href="/search/haproxy/1.htm">haproxy</a><a class="tag" taget="_blank" href="/search/%E9%AB%98%E5%8F%AF%E7%94%A8/1.htm">高可用</a> <div>我们的应用MyApp不支持集群,但要求双机单活(两台机器:master和slave): 1.正常情况下,只有master启动MyApp并提供服务 2.当master发生故障时,slave自动启动本机的MyApp,同时虚拟IP漂移至slave,保持对外提供服务的IP和端口不变 F5据说也能满足上面的需求,但F5的通常用法都是双机双活,单活的话还没研究过 服务器资源 10.7</div> </li> <li><a href="/article/364.htm" title="eclipse编辑器中文乱码问题解决" target="_blank">eclipse编辑器中文乱码问题解决</a> <span class="text-muted">0624chenhong</span> <a class="tag" taget="_blank" href="/search/eclipse%E4%B9%B1%E7%A0%81/1.htm">eclipse乱码</a> <div>使用Eclipse编辑文件经常出现中文乱码或者文件中有中文不能保存的问题,Eclipse提供了灵活的设置文件编码格式的选项,我们可以通过设置编码 格式解决乱码问题。在Eclipse可以从几个层面设置编码格式:Workspace、Project、Content Type、File 本文以Eclipse 3.3(英文)为例加以说明: 1. 设置Workspace的编码格式: Windows-&g</div> </li> <li><a href="/article/491.htm" title="基础篇--resources资源" target="_blank">基础篇--resources资源</a> <span class="text-muted">不懂事的小屁孩</span> <a class="tag" taget="_blank" href="/search/android/1.htm">android</a> <div>最近一直在做java开发,偶尔敲点android代码,突然发现有些基础给忘记了,今天用半天时间温顾一下resources的资源。 String.xml    字符串资源   涉及国际化问题  http://www.2cto.com/kf/201302/190394.html   string-array</div> </li> <li><a href="/article/618.htm" title="接上篇补上window平台自动上传证书文件的批处理问卷" target="_blank">接上篇补上window平台自动上传证书文件的批处理问卷</a> <span class="text-muted">酷的飞上天空</span> <a class="tag" taget="_blank" href="/search/window/1.htm">window</a> <div> @echo off : host=服务器证书域名或ip,需要和部署时服务器的域名或ip一致 ou=公司名称, o=公司名称 set host=localhost set ou=localhost set o=localhost set password=123456 set validity=3650 set salias=s</div> </li> <li><a href="/article/745.htm" title="企业物联网大潮涌动:如何做好准备?" target="_blank">企业物联网大潮涌动:如何做好准备?</a> <span class="text-muted">蓝儿唯美</span> <a class="tag" taget="_blank" href="/search/%E4%BC%81%E4%B8%9A/1.htm">企业</a> <div>物联网的可能性也许是无限的。要找出架构师可以做好准备的领域然后利用日益连接的世界。 尽管物联网(IoT)还很新,企业架构师现在也应该为一个连接更加紧密的未来做好计划,而不是跟上闸门被打开后的集成挑战。“问题不在于物联网正在进入哪些领域,而是哪些地方物联网没有在企业推进,” Gartner研究总监Mike Walker说。 Gartner预测到2020年物联网设备安装量将达260亿,这些设备在全</div> </li> <li><a href="/article/872.htm" title="spring学习——数据库(mybatis持久化框架配置)" target="_blank">spring学习——数据库(mybatis持久化框架配置)</a> <span class="text-muted">a-john</span> <a class="tag" taget="_blank" href="/search/mybatis/1.htm">mybatis</a> <div>Spring提供了一组数据访问框架,集成了多种数据访问技术。无论是JDBC,iBATIS(mybatis)还是Hibernate,Spring都能够帮助消除持久化代码中单调枯燥的数据访问逻辑。可以依赖Spring来处理底层的数据访问。 mybatis是一种Spring持久化框架,要使用mybatis,就要做好相应的配置: 1,配置数据源。有很多数据源可以选择,如:DBCP,JDBC,aliba</div> </li> <li><a href="/article/999.htm" title="Java静态代理、动态代理实例" target="_blank">Java静态代理、动态代理实例</a> <span class="text-muted">aijuans</span> <a class="tag" taget="_blank" href="/search/Java%E9%9D%99%E6%80%81%E4%BB%A3%E7%90%86/1.htm">Java静态代理</a> <div> 采用Java代理模式,代理类通过调用委托类对象的方法,来提供特定的服务。委托类需要实现一个业务接口,代理类返回委托类的实例接口对象。 按照代理类的创建时期,可以分为:静态代理和动态代理。 所谓静态代理: 指程序员创建好代理类,编译时直接生成代理类的字节码文件。 所谓动态代理: 在程序运行时,通过反射机制动态生成代理类。   一、静态代理类实例: 1、Serivce.ja</div> </li> <li><a href="/article/1126.htm" title="Struts1与Struts2的12点区别" target="_blank">Struts1与Struts2的12点区别</a> <span class="text-muted">asia007</span> <a class="tag" taget="_blank" href="/search/Struts1%E4%B8%8EStruts2/1.htm">Struts1与Struts2</a> <div>1) 在Action实现类方面的对比:Struts 1要求Action类继承一个抽象基类;Struts 1的一个具体问题是使用抽象类编程而不是接口。Struts 2 Action类可以实现一个Action接口,也可以实现其他接口,使可选和定制的服务成为可能。Struts 2提供一个ActionSupport基类去实现常用的接口。即使Action接口不是必须实现的,只有一个包含execute方法的P</div> </li> <li><a href="/article/1253.htm" title="初学者要多看看帮助文档 不要用js来写Jquery的代码" target="_blank">初学者要多看看帮助文档 不要用js来写Jquery的代码</a> <span class="text-muted">百合不是茶</span> <a class="tag" taget="_blank" href="/search/jquery/1.htm">jquery</a><a class="tag" taget="_blank" href="/search/js/1.htm">js</a> <div>解析json数据的时候需要将解析的数据写到文本框中,  出现了用js来写Jquery代码的问题;   1, JQuery的赋值  有问题    代码如下: data.username 表示的是:  网易            $("#use</div> </li> <li><a href="/article/1380.htm" title="经理怎么和员工搞好关系和信任" target="_blank">经理怎么和员工搞好关系和信任</a> <span class="text-muted">bijian1013</span> <a class="tag" taget="_blank" href="/search/%E5%9B%A2%E9%98%9F/1.htm">团队</a><a class="tag" taget="_blank" href="/search/%E9%A1%B9%E7%9B%AE%E7%AE%A1%E7%90%86/1.htm">项目管理</a><a class="tag" taget="_blank" href="/search/%E7%AE%A1%E7%90%86/1.htm">管理</a> <div>        产品经理应该有坚实的专业基础,这里的基础包括产品方向和产品策略的把握,包括设计,也包括对技术的理解和见识,对运营和市场的敏感,以及良好的沟通和协作能力。换言之,既然是产品经理,整个产品的方方面面都应该能摸得出门道。这也不懂那也不懂,如何让人信服?如何让自己懂?就是不断学习,不仅仅从书本中,更从平时和各种角色的沟通</div> </li> <li><a href="/article/1507.htm" title="如何为rich:tree不同类型节点设置右键菜单" target="_blank">如何为rich:tree不同类型节点设置右键菜单</a> <span class="text-muted">sunjing</span> <a class="tag" taget="_blank" href="/search/contextMenu/1.htm">contextMenu</a><a class="tag" taget="_blank" href="/search/tree/1.htm">tree</a><a class="tag" taget="_blank" href="/search/Richfaces/1.htm">Richfaces</a> <div>组合使用target和targetSelector就可以啦,如下: <rich:tree id="ruleTree" value="#{treeAction.ruleTree}" var="node" nodeType="#{node.type}" selectionChangeListener=&qu</div> </li> <li><a href="/article/1634.htm" title="【Redis二】Redis2.8.17搭建主从复制环境" target="_blank">【Redis二】Redis2.8.17搭建主从复制环境</a> <span class="text-muted">bit1129</span> <a class="tag" taget="_blank" href="/search/redis/1.htm">redis</a> <div>开始使用Redis2.8.17 Redis第一篇在Redis2.4.5上搭建主从复制环境,对它的主从复制的工作机制,真正的惊呆了。不知道Redis2.8.17的主从复制机制是怎样的,Redis到了2.4.5这个版本,主从复制还做成那样,Impossible is nothing! 本篇把主从复制环境再搭一遍看看效果,这次在Unbuntu上用官方支持的版本。   Ubuntu上安装Red</div> </li> <li><a href="/article/1761.htm" title="JSONObject转换JSON--将Date转换为指定格式" target="_blank">JSONObject转换JSON--将Date转换为指定格式</a> <span class="text-muted">白糖_</span> <a class="tag" taget="_blank" href="/search/JSONObject/1.htm">JSONObject</a> <div>项目中,经常会用JSONObject插件将JavaBean或List<JavaBean>转换为JSON格式的字符串,而JavaBean的属性有时候会有java.util.Date这个类型的时间对象,这时JSONObject默认会将Date属性转换成这样的格式:   {"nanos":0,"time":-27076233600000,</div> </li> <li><a href="/article/1888.htm" title="JavaScript语言精粹读书笔记" target="_blank">JavaScript语言精粹读书笔记</a> <span class="text-muted">braveCS</span> <a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a> <div>【经典用法】:   //①定义新方法 Function .prototype.method=function(name, func){ this.prototype[name]=func; return this; } //②给Object增加一个create方法,这个方法创建一个使用原对</div> </li> <li><a href="/article/2015.htm" title="编程之美-找符合条件的整数 用字符串来表示大整数避免溢出" target="_blank">编程之美-找符合条件的整数 用字符串来表示大整数避免溢出</a> <span class="text-muted">bylijinnan</span> <a class="tag" taget="_blank" href="/search/%E7%BC%96%E7%A8%8B%E4%B9%8B%E7%BE%8E/1.htm">编程之美</a> <div> import java.util.LinkedList; public class FindInteger { /** * 编程之美 找符合条件的整数 用字符串来表示大整数避免溢出 * 题目:任意给定一个正整数N,求一个最小的正整数M(M>1),使得N*M的十进制表示形式里只含有1和0 * * 假设当前正在搜索由0,1组成的K位十进制数</div> </li> <li><a href="/article/2142.htm" title="读书笔记" target="_blank">读书笔记</a> <span class="text-muted">chengxuyuancsdn</span> <a class="tag" taget="_blank" href="/search/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/1.htm">读书笔记</a> <div>1、Struts访问资源 2、把静态参数传递给一个动作 3、<result>type属性 4、s:iterator、s:if c:forEach 5、StringBuilder和StringBuffer 6、spring配置拦截器 1、访问资源 (1)通过ServletActionContext对象和实现ServletContextAware,ServletReque</div> </li> <li><a href="/article/2269.htm" title="[通讯与电力]光网城市建设的一些问题" target="_blank">[通讯与电力]光网城市建设的一些问题</a> <span class="text-muted">comsci</span> <a class="tag" taget="_blank" href="/search/%E9%97%AE%E9%A2%98/1.htm">问题</a> <div>       信号防护的问题,前面已经说过了,这里要说光网交换机与市电保障的关系       我们过去用的ADSL线路,因为是电话线,在小区和街道电力中断的情况下,只要在家里用笔记本电脑+蓄电池,连接ADSL,同样可以上网........     </div> </li> <li><a href="/article/2396.htm" title="oracle 空间RESUMABLE" target="_blank">oracle 空间RESUMABLE</a> <span class="text-muted">daizj</span> <a class="tag" taget="_blank" href="/search/oracle/1.htm">oracle</a><a class="tag" taget="_blank" href="/search/%E7%A9%BA%E9%97%B4%E4%B8%8D%E8%B6%B3/1.htm">空间不足</a><a class="tag" taget="_blank" href="/search/RESUMABLE/1.htm">RESUMABLE</a><a class="tag" taget="_blank" href="/search/%E9%94%99%E8%AF%AF%E6%8C%82%E8%B5%B7/1.htm">错误挂起</a> <div>空间RESUMABLE操作  转 Oracle从9i开始引入这个功能,当出现空间不足等相关的错误时,Oracle可以不是马上返回错误信息,并回滚当前的操作,而是将操作挂起,直到挂起时间超过RESUMABLE TIMEOUT,或者空间不足的错误被解决。 这一篇简单介绍空间RESUMABLE的例子。 第一次碰到这个特性是在一次安装9i数据库的过程中,在利用D</div> </li> <li><a href="/article/2523.htm" title="重构第一次写的线程池" target="_blank">重构第一次写的线程池</a> <span class="text-muted">dieslrae</span> <a class="tag" taget="_blank" href="/search/%E7%BA%BF%E7%A8%8B%E6%B1%A0+python/1.htm">线程池 python</a> <div>最近没有什么学习欲望,修改之前的线程池的计划一直搁置,这几天比较闲,还是做了一次重构,由之前的2个类拆分为现在的4个类. 1、首先是工作线程类:TaskThread,此类为一个工作线程,用于完成一个工作任务,提供等待(wait),继续(proceed),绑定任务(bindTask)等方法 #!/usr/bin/env python # -*- coding:utf8 -*- </div> </li> <li><a href="/article/2650.htm" title="C语言学习六指针" target="_blank">C语言学习六指针</a> <span class="text-muted">dcj3sjt126com</span> <a class="tag" taget="_blank" href="/search/c/1.htm">c</a> <div>初识指针,简单示例程序: /* 指针就是地址,地址就是指针 地址就是内存单元的编号 指针变量是存放地址的变量 指针和指针变量是两个不同的概念 但是要注意: 通常我们叙述时会把指针变量简称为指针,实际它们含义并不一样 */ # include <stdio.h> int main(void) { int * p; // p是变量的名字, int * </div> </li> <li><a href="/article/2777.htm" title="yii2 beforeSave afterSave beforeDelete" target="_blank">yii2 beforeSave afterSave beforeDelete</a> <span class="text-muted">dcj3sjt126com</span> <a class="tag" taget="_blank" href="/search/delete/1.htm">delete</a> <div>public function afterSave($insert, $changedAttributes) { parent::afterSave($insert, $changedAttributes); if($insert) { //这里是新增数据 } else { //这里是更新数据 } }  </div> </li> <li><a href="/article/2904.htm" title="timertask" target="_blank">timertask</a> <span class="text-muted">shuizhaosi888</span> <a class="tag" taget="_blank" href="/search/timertask/1.htm">timertask</a> <div>java.util.Timer timer = new java.util.Timer(true); // true 说明这个timer以daemon方式运行(优先级低, // 程序结束timer也自动结束),注意,javax.swing // 包中也有一个Timer类,如果import中用到swing包, // 要注意名字的冲突。 TimerTask task = new</div> </li> <li><a href="/article/3031.htm" title="Spring Security(13)——session管理" target="_blank">Spring Security(13)——session管理</a> <span class="text-muted">234390216</span> <a class="tag" taget="_blank" href="/search/session/1.htm">session</a><a class="tag" taget="_blank" href="/search/Spring+Security/1.htm">Spring Security</a><a class="tag" taget="_blank" href="/search/%E6%94%BB%E5%87%BB%E4%BF%9D%E6%8A%A4/1.htm">攻击保护</a><a class="tag" taget="_blank" href="/search/%E8%B6%85%E6%97%B6/1.htm">超时</a> <div>session管理 目录   1.1     检测session超时 1.2     concurrency-control 1.3     session 固定攻击保护         </div> </li> <li><a href="/article/3158.htm" title="公司项目NODEJS实践0.3[ mongo / session ...]" target="_blank">公司项目NODEJS实践0.3[ mongo / session ...]</a> <span class="text-muted">逐行分析JS源代码</span> <a class="tag" taget="_blank" href="/search/mongodb/1.htm">mongodb</a><a class="tag" taget="_blank" href="/search/session/1.htm">session</a><a class="tag" taget="_blank" href="/search/nodejs/1.htm">nodejs</a> <div>    http://www.upopen.cn   一、前言         书接上回,我们搭建了WEB服务端路由、模板等功能,完成了register 通过ajax与后端的通信,今天主要完成数据与mongodb的存取,实现注册 / 登录 /</div> </li> <li><a href="/article/3285.htm" title="pojo.vo.po.domain区别" target="_blank">pojo.vo.po.domain区别</a> <span class="text-muted">LiaoJuncai</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/VO/1.htm">VO</a><a class="tag" taget="_blank" href="/search/POJO/1.htm">POJO</a><a class="tag" taget="_blank" href="/search/javabean/1.htm">javabean</a><a class="tag" taget="_blank" href="/search/domain/1.htm">domain</a> <div>  POJO = "Plain Old Java Object",是MartinFowler等发明的一个术语,用来表示普通的Java对象,不是JavaBean, EntityBean 或者 SessionBean。POJO不但当任何特殊的角色,也不实现任何特殊的Java框架的接口如,EJB, JDBC等等。      即POJO是一个简单的普通的Java对象,它包含业务逻辑</div> </li> <li><a href="/article/3412.htm" title="Windows Error Code" target="_blank">Windows Error Code</a> <span class="text-muted">OhMyCC</span> <a class="tag" taget="_blank" href="/search/windows/1.htm">windows</a> <div>0 操作成功完成. 1 功能错误. 2 系统找不到指定的文件. 3 系统找不到指定的路径. 4 系统无法打开文件. 5 拒绝访问. 6 句柄无效. 7 存储控制块被损坏. 8 存储空间不足, 无法处理此命令. 9 存储控制块地址无效. 10 环境错误. 11 试图加载格式错误的程序. 12 访问码无效. 13 数据无效. 14 存储器不足, 无法完成此操作. 15 系</div> </li> <li><a href="/article/3539.htm" title="在storm集群环境下发布Topology" target="_blank">在storm集群环境下发布Topology</a> <span class="text-muted">roadrunners</span> <a class="tag" taget="_blank" href="/search/%E9%9B%86%E7%BE%A4/1.htm">集群</a><a class="tag" taget="_blank" href="/search/storm/1.htm">storm</a><a class="tag" taget="_blank" href="/search/topology/1.htm">topology</a><a class="tag" taget="_blank" href="/search/spout/1.htm">spout</a><a class="tag" taget="_blank" href="/search/bolt/1.htm">bolt</a> <div>storm的topology设计和开发就略过了。本章主要来说说如何在storm的集群环境中,通过storm的管理命令来发布和管理集群中的topology。   1、打包 打包插件是使用maven提供的maven-shade-plugin,详细见maven-shade-plugin。 <plugin> <groupId>org.apache.maven.</div> </li> <li><a href="/article/3666.htm" title="为什么不允许代码里出现“魔数”" target="_blank">为什么不允许代码里出现“魔数”</a> <span class="text-muted">tomcat_oracle</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a> <div>  在一个新项目中,我最先做的事情之一,就是建立使用诸如Checkstyle和Findbugs之类工具的准则。目的是制定一些代码规范,以及避免通过静态代码分析就能够检测到的bug。   迟早会有人给出案例说这样太离谱了。其中的一个案例是Checkstyle的魔数检查。它会对任何没有定义常量就使用的数字字面量给出警告,除了-1、0、1和2。   很多开发者在这个检查方面都有问题,这可以从结果</div> </li> <li><a href="/article/3793.htm" title="zoj 3511 Cake Robbery(线段树)" target="_blank">zoj 3511 Cake Robbery(线段树)</a> <span class="text-muted">阿尔萨斯</span> <a class="tag" taget="_blank" href="/search/%E7%BA%BF%E6%AE%B5%E6%A0%91/1.htm">线段树</a> <div> 题目链接:zoj 3511 Cake Robbery 题目大意:就是有一个N边形的蛋糕,切M刀,从中挑选一块边数最多的,保证没有两条边重叠。 解题思路:有多少个顶点即为有多少条边,所以直接按照切刀切掉点的个数排序,然后用线段树维护剩下的还有哪些点。 #include <cstdio> #include <cstring> #include <vector&</div> </li> </ul> </div> </div> </div> <div> <div class="container"> <div class="indexes"> <strong>按字母分类:</strong> <a href="/tags/A/1.htm" target="_blank">A</a><a href="/tags/B/1.htm" target="_blank">B</a><a href="/tags/C/1.htm" target="_blank">C</a><a href="/tags/D/1.htm" target="_blank">D</a><a href="/tags/E/1.htm" target="_blank">E</a><a href="/tags/F/1.htm" target="_blank">F</a><a href="/tags/G/1.htm" target="_blank">G</a><a href="/tags/H/1.htm" target="_blank">H</a><a href="/tags/I/1.htm" target="_blank">I</a><a href="/tags/J/1.htm" target="_blank">J</a><a href="/tags/K/1.htm" target="_blank">K</a><a href="/tags/L/1.htm" target="_blank">L</a><a href="/tags/M/1.htm" target="_blank">M</a><a href="/tags/N/1.htm" target="_blank">N</a><a href="/tags/O/1.htm" target="_blank">O</a><a href="/tags/P/1.htm" target="_blank">P</a><a href="/tags/Q/1.htm" target="_blank">Q</a><a href="/tags/R/1.htm" target="_blank">R</a><a href="/tags/S/1.htm" target="_blank">S</a><a href="/tags/T/1.htm" target="_blank">T</a><a href="/tags/U/1.htm" target="_blank">U</a><a href="/tags/V/1.htm" target="_blank">V</a><a href="/tags/W/1.htm" target="_blank">W</a><a href="/tags/X/1.htm" target="_blank">X</a><a href="/tags/Y/1.htm" target="_blank">Y</a><a href="/tags/Z/1.htm" target="_blank">Z</a><a href="/tags/0/1.htm" target="_blank">其他</a> </div> </div> </div> <footer id="footer" class="mb30 mt30"> <div class="container"> <div class="footBglm"> <a target="_blank" href="/">首页</a> - <a target="_blank" href="/custom/about.htm">关于我们</a> - <a target="_blank" href="/search/Java/1.htm">站内搜索</a> - <a target="_blank" href="/sitemap.txt">Sitemap</a> - <a target="_blank" href="/custom/delete.htm">侵权投诉</a> </div> <div class="copyright">版权所有 IT知识库 CopyRight © 2000-2050 E-COM-NET.COM , All Rights Reserved. <!-- <a href="https://beian.miit.gov.cn/" rel="nofollow" target="_blank">京ICP备09083238号</a><br>--> </div> </div> </footer> <!-- 代码高亮 --> <script type="text/javascript" src="/static/syntaxhighlighter/scripts/shCore.js"></script> <script type="text/javascript" src="/static/syntaxhighlighter/scripts/shLegacy.js"></script> <script type="text/javascript" src="/static/syntaxhighlighter/scripts/shAutoloader.js"></script> <link type="text/css" rel="stylesheet" href="/static/syntaxhighlighter/styles/shCoreDefault.css"/> <script type="text/javascript" src="/static/syntaxhighlighter/src/my_start_1.js"></script> </body> </html>