Jekyll2020-12-19T11:10:12+00:00https://tech.codefog.com/feed.xmlcodefogThe more you know, the more you know you don't know.Rickyat20s@sina.comnginx反向代理https配置方法与实现请求的负载均衡详解2019-07-31T00:00:00+00:002019-07-31T00:00:00+00:00https://tech.codefog.com/2019/reverse-proxy-and-traffic-sla<h2 id="heading-nginx反向代理的设置方法">Nginx反向代理的设置方法</h2>
<p>nginx反向代理有很多的不同方面的用处, 这里主要讲如何设置docker的反向代理, 把本地的docker环境映射到域名上去.</p>
<h3 id="heading-系统环境">系统环境</h3>
<p>docker + nginx + 公网IP + 域名</p>
<h3 id="heading-操作方法">操作方法</h3>
<ol>
<li>首先在启动docker时, 把docker内部端口使用<code class="highlighter-rouge">-p 外部端口:内部端口</code>映射到服务器的网络环境中, 不用给当前的docker容器创建docker网络环境.</li>
<li>然后编写nginx配置文件, 我是用oneinstack可以直接创建nginx的conf配置并且自动生成免费的SSL证书, 操作简单.</li>
<li>删掉oninstack在nginx配置文件中生成的对图片和其他资源文件处理的location配置, 加入如下的反向代理语句:
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:6001; #自行修改为你需要的配置
}
</code></pre></div> </div>
<p>上面的配置可以把6001端口的服务代理到其他端口,我在使用过程中是代理到了80端口, 之后使用域名进行解析.</p>
</li>
</ol>
<h2 id="heading-负载均衡的配置方法">负载均衡的配置方法</h2>
<p>在nginx中负载均衡配置方式类似于反向代理, 但是负载均衡主要通过<code class="highlighter-rouge">upstream</code>模块来完成,简单配置方法如下,此时
采用的是轮询算法:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>upstream test {
server 192.168.0.1;
server 192.168.0.2;
}
</code></pre></div></div>
<p>nginx可以配置不同的算法,比如<a href="https://blog.csdn.net/weixin_42075590/article/details/80631439">ip hash机制</a>,
也可以配置轮询的权重,如下:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>upstream tomcat_pool
{
#server tomcat地址:端口号 weight表示权值,权值越大,被分配的几率越大;
server 192.168.0.223:8080 weight=4 max_fails=2 fail_timeout=30s;
server 192.168.0.224:8080 weight=4 max_fails=2 fail_timeout=30s;
}
#默认请求设置
location / {
proxy_pass http://tomcat_pool; #转向tomcat处理
}
</code></pre></div></div>
<p>上述例子是对TOMCAT做负载均衡,其他服务类似.对nginx负载均衡或者upstream模块更详细的讲解请参考<a href="http://tengine.taobao.org/book/chapter_05.html#upstream">Nginx开发从入门到精通:upstream模块</a>.</p>
<h2 id="heading-参考">参考</h2>
<p>http://wiki.jikexueyuan.com/project/nginx/load-balancing-module.html<br />
http://tengine.taobao.org/book/chapter_05.html#upstream<br />
https://www.cnblogs.com/youzhibing/p/7327342.html</p>Rickyat20s@sina.comNginx反向代理的设置方法 nginx反向代理有很多的不同方面的用处, 这里主要讲如何设置docker的反向代理, 把本地的docker环境映射到域名上去. 系统环境 docker + nginx + 公网IP + 域名 操作方法 首先在启动docker时, 把docker内部端口使用-p 外部端口:内部端口映射到服务器的网络环境中, 不用给当前的docker容器创建docker网络环境. 然后编写nginx配置文件, 我是用oneinstack可以直接创建nginx的conf配置并且自动生成免费的SSL证书, 操作简单. 删掉oninstack在nginx配置文件中生成的对图片和其他资源文件处理的location配置, 加入如下的反向代理语句: location / { proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://127.0.0.1:6001; #自行修改为你需要的配置 } 上面的配置可以把6001端口的服务代理到其他端口,我在使用过程中是代理到了80端口, 之后使用域名进行解析.解决Linux关不了机开机,报错NMI watchdog: BUG: soft lockup - CPU#2 stuck for 22s的bug2018-11-24T00:00:00+00:002018-11-24T00:00:00+00:00https://tech.codefog.com/2018/NMI-Watchdog-bug-soft-lockup-cpu-stack<h2 id="heading-问题描述">问题描述</h2>
<p>在安装完Ubuntu或者其他Linux, 关机时会卡死, 循环报错<code class="highlighter-rouge">NMI watchdog: BUG: soft lockup - CPU#2 stuck for 22s!</code>, 无法关机. 在本人的测试中, Centos18xx版本和Ubuntu16-18均出现了上述问题, 经过一些尝试后, 成功找到了解决方法.</p>
<h2 id="heading-问题分析">问题分析</h2>
<p>初步排查, 定位在显卡驱动上. 我实在一个老MSI笔记本上安装的Linux, 它自带一个GTX960M的独立显卡, 然而, Linux对NVIDIA的显卡一向支持的很差, 会出现各种奇怪的问题. 这次的原因很可能就是它.</p>
<h2 id="heading-解决方法">解决方法</h2>
<p>再开机显示<code class="highlighter-rouge">GRUB2</code>界面的时候, 选中你要进入的那个内核版本, 按<code class="highlighter-rouge">e</code>, 在Linux内核命令行(以Linux开头的那一行)末尾添加<code class="highlighter-rouge">nouveau.modeset=0</code>.这样可以正常进入系统, 直接修改你的<code class="highlighter-rouge">grub</code>文件, 把上述添加的命令写进去, 之后执行grub更新, 这样的问题就应该不会复现.</p>
<h2 id="heading-建议">建议</h2>
<p>如果你的电脑/笔记本可以屏蔽独立显卡或者只是用CPU集成显卡, 请屏蔽掉独立显卡并且不要再开启了. 如果你需要Linux的图形界面,可以在开机进入系统后把显卡驱动换成<code class="highlighter-rouge">NVIDIA</code>自带的驱动,问题就会解决.台式机或者AMD平台暂未测试.</p>Rickyat20s@sina.com问题描述 在安装完Ubuntu或者其他Linux, 关机时会卡死, 循环报错NMI watchdog: BUG: soft lockup - CPU#2 stuck for 22s!, 无法关机. 在本人的测试中, Centos18xx版本和Ubuntu16-18均出现了上述问题, 经过一些尝试后, 成功找到了解决方法.如何在Ubuntu/Centos上安装Wireguard工具 | how to install Wireguard on Ubuntu/CentOS2018-11-12T00:00:00+00:002018-11-12T00:00:00+00:00https://tech.codefog.com/2018/how-to-install-wireguard<h2 id="heading-需求介绍">需求介绍</h2>
<p>在做毕业设计的过程中,需要一台高性能的服务器,如果在阿里云等云服务购买的话成本太高,于是把一台老的MSI笔记本安装了<code class="highlighter-rouge">Ubuntu Server 16.04.5</code>. 在开发的过程中,我<code class="highlighter-rouge">可能不会和上述服务器在同一个局域网内</code>,所以就需要组建一个VPN网络.<br />
经过查找,现成的符合要求的只有如下选择:</p>
<ol>
<li>花生壳以及他们公司的一套产品(收费,不推荐)</li>
<li>FRP</li>
<li>OpenVPN%Softether</li>
<li>Wireguard</li>
</ol>
<h2 id="heading-wireguard的优势">Wireguard的优势</h2>
<ol>
<li>配置简单,仅需要公钥秘钥加密解密即可</li>
<li>速度性能好,在最新的Linux内核上,可以跑满宽带(100M+CN2双向线路)</li>
<li>服务器资源占用少(内存少,在跑满100M之后,占用CPU30% E5-26XX, 单核心)</li>
</ol>
<h2 id="heading-安装配置方法">安装,配置方法</h2>
<p>Ubuntu</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">sudo </span>add-apt-repository ppa:wireguard/wireguard
<span class="nv">$ </span><span class="nb">sudo </span>apt-get update
<span class="nv">$ </span><span class="nb">sudo </span>apt-get <span class="nb">install </span>wireguard
</code></pre></div></div>
<p>Centos</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">sudo </span>curl <span class="nt">-Lo</span> /etc/yum.repos.d/wireguard.repo https://copr.fedorainfracloud.org/coprs/jdoss/wireguard/repo/epel-7/jdoss-wireguard-epel-7.repo
<span class="nv">$ </span><span class="nb">sudo </span>yum <span class="nb">install </span>epel-release
<span class="nv">$ </span><span class="nb">sudo </span>yum <span class="nb">install </span>wireguard-dkms wireguard-tools
</code></pre></div></div>
<p>直接执行上述命令,即可成功安装,无需其他操作.wireguard不区分服务器和客户机,只需要开启一个虚拟网卡,就实现了互通.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code># ip link add dev wg0 type wireguard
# ip address add dev wg0 192.168.2.1/24
# wg setconf wg0 myconfig.conf
</code></pre></div></div>
<p>如上为核心命令,公钥和私钥可以通过<code class="highlighter-rouge">wg genkey</code>来产生私钥,<code class="highlighter-rouge">wg pubkey < privateKey</code>产生公钥.<br />
配置文件如下:</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">[</span>Interface]
PrivateKey <span class="o">=</span> XXXXX
Address <span class="o">=</span> 10.0.0.1/24
PostUp <span class="o">=</span> iptables <span class="nt">-A</span> FORWARD <span class="nt">-i</span> wg0 <span class="nt">-j</span> ACCEPT<span class="p">;</span> iptables <span class="nt">-A</span> FORWARD <span class="nt">-o</span> wg0 <span class="nt">-j</span> ACCEPT<span class="p">;</span> iptables <span class="nt">-t</span> nat <span class="nt">-A</span> POSTROUTING <span class="nt">-o</span> eth0 <span class="nt">-j</span> MASQUERADE
PostDown <span class="o">=</span> iptables <span class="nt">-D</span> FORWARD <span class="nt">-i</span> wg0 <span class="nt">-j</span> ACCEPT<span class="p">;</span> iptables <span class="nt">-D</span> FORWARD <span class="nt">-o</span> wg0 <span class="nt">-j</span> ACCEPT<span class="p">;</span> iptables <span class="nt">-t</span> nat <span class="nt">-D</span> POSTROUTING <span class="nt">-o</span> eth0 <span class="nt">-j</span> MASQUERADE
ListenPort <span class="o">=</span> xxx
DNS <span class="o">=</span> 8.8.8.8
MTU <span class="o">=</span> 1420
<span class="o">[</span>Peer]
PublicKey <span class="o">=</span> XXXXX
AllowedIPs <span class="o">=</span> 10.0.0.2/32
</code></pre></div></div>
<p>之后使用<code class="highlighter-rouge">wg-quick up/down XXX</code>启动服务,服务器客户端一样.XXX为XXX.conf的前缀.具体文档请看官网https://www.wireguard.com/quickstart/.</p>
<h2 id="heading-存在问题">存在问题</h2>
<p>暂时没有简单易用的GUI客户端.</p>Rickyat20s@sina.com需求介绍 在做毕业设计的过程中,需要一台高性能的服务器,如果在阿里云等云服务购买的话成本太高,于是把一台老的MSI笔记本安装了Ubuntu Server 16.04.5. 在开发的过程中,我可能不会和上述服务器在同一个局域网内,所以就需要组建一个VPN网络. 经过查找,现成的符合要求的只有如下选择: 花生壳以及他们公司的一套产品(收费,不推荐) FRP OpenVPN%Softether Wireguard正则表达式以及它在java中的常见用法2018-09-18T00:00:00+00:002018-09-18T00:00:00+00:00https://tech.codefog.com/2018/how-to-regex-in-javaRickyat20s@sina.com算法 - java常见算法题输入输出2018-09-18T00:00:00+00:002018-09-18T00:00:00+00:00https://tech.codefog.com/2018/java-basic-input-output<p>字符串和数字相同道理,本文都适用于字符串。</p>
<h2 id="heading-输入一行数字">输入一行数字</h2>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">Scanner</span> <span class="n">sc</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Scanner</span><span class="o">(</span><span class="nc">System</span><span class="o">.</span><span class="na">in</span><span class="o">);</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"读取一行数字:"</span><span class="o">);</span>
<span class="nc">String</span> <span class="n">oneLine</span> <span class="o">=</span> <span class="n">sc</span><span class="o">.</span><span class="na">nextLine</span><span class="o">();</span>
<span class="nc">String</span><span class="o">[]</span> <span class="n">cs</span> <span class="o">=</span> <span class="n">oneLine</span><span class="o">.</span><span class="na">split</span><span class="o">(</span><span class="s">" "</span><span class="o">);</span>
<span class="k">for</span> <span class="o">(</span><span class="nc">String</span> <span class="n">x</span> <span class="o">:</span> <span class="n">cs</span><span class="o">)</span> <span class="o">{</span>
<span class="kt">int</span> <span class="n">intValue</span> <span class="o">=</span> <span class="nc">Integer</span><span class="o">.</span><span class="na">valueOf</span><span class="o">(</span><span class="n">x</span><span class="o">);</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">print</span><span class="o">(</span><span class="n">intValue</span> <span class="o">+</span> <span class="s">" "</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div></div>
<h2 id="heading-输入n行数字行数确定">输入n行数字,行数确定</h2>
<p>如果需要获得每行数字的值,用String的split方法分割为<code class="highlighter-rouge">char[]</code>后,再使用<code class="highlighter-rouge">Integer.valueOf()</code>转换成int即可,同上</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"读取n行数字:"</span><span class="o">);</span>
<span class="kt">int</span> <span class="n">lines</span> <span class="o">=</span> <span class="mi">3</span><span class="o">;</span>
<span class="nc">String</span><span class="o">[]</span> <span class="n">mutiLines</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">String</span><span class="o">[</span><span class="mi">3</span><span class="o">];</span>
<span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span>
<span class="k">while</span> <span class="o">(</span><span class="n">i</span> <span class="o"><</span> <span class="n">lines</span><span class="o">)</span> <span class="o">{</span>
<span class="n">mutiLines</span><span class="o">[</span><span class="n">i</span><span class="o">++]</span> <span class="o">=</span> <span class="n">sc</span><span class="o">.</span><span class="na">nextLine</span><span class="o">();</span>
<span class="o">}</span>
<span class="k">for</span> <span class="o">(</span><span class="nc">String</span> <span class="n">s</span> <span class="o">:</span> <span class="n">mutiLines</span><span class="o">)</span> <span class="o">{</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">s</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div></div>
<h2 id="heading-输入多行数字未知行数">输入多行数字,未知行数</h2>
<p>没有对一行多数字做处理,处理方法和上述但行输入相同。</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"输入多行数字:"</span><span class="o">);</span>
<span class="nc">List</span><span class="o"><</span><span class="nc">String</span><span class="o">></span> <span class="n">list</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ArrayList</span><span class="o"><>();</span>
<span class="nc">String</span> <span class="n">input</span> <span class="o">=</span> <span class="s">""</span><span class="o">;</span>
<span class="k">while</span> <span class="o">(</span><span class="kc">true</span><span class="o">)</span> <span class="o">{</span>
<span class="n">input</span> <span class="o">=</span> <span class="n">sc</span><span class="o">.</span><span class="na">nextLine</span><span class="o">();</span>
<span class="k">if</span> <span class="o">(!</span><span class="n">input</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="s">"q"</span><span class="o">))</span> <span class="o">{</span>
<span class="n">list</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">input</span><span class="o">);</span>
<span class="o">}</span><span class="k">else</span> <span class="o">{</span>
<span class="k">break</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="k">for</span> <span class="o">(</span><span class="nc">String</span> <span class="n">s</span> <span class="o">:</span> <span class="n">list</span><span class="o">)</span> <span class="o">{</span>
<span class="c1">//只能转换一行一个数字,多个数字需要额外同上的操作</span>
<span class="c1">//int intValue = Integer.valueOf(s);</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">s</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div></div>
<h2 id="heading-遇到其他情况再补充">遇到其他情况再补充</h2>Rickyat20s@sina.com字符串和数字相同道理,本文都适用于字符串。算法 - 字符串包含[+++]2018-09-18T00:00:00+00:002018-09-18T00:00:00+00:00https://tech.codefog.com/2018/string-contains<h2 id="heading-题目简介">题目简介</h2>
<p>给定一长字符串<code class="highlighter-rouge">a -> ABCD</code>,短字符串<code class="highlighter-rouge">b -> BAD</code>, 短字符串<code class="highlighter-rouge">c -> BCE</code>,则字符串b中的字母都在字符串a中,b是a的真子集,所以对于a,返回<code class="highlighter-rouge">true</code>,对于b,返回<code class="highlighter-rouge">false</code>,因为字符串b的元素E不在a中。<br />
注意:都是大写字母</p>
<h2 id="heading-解法1暴力轮询">解法1,暴力轮询</h2>
<p>拿出字符串b的每个元素,分别查询是否在a中出现,若一旦有一个不出现,则返回<code class="highlighter-rouge">false</code>,如果所有元素都出现,则返回<code class="highlighter-rouge">true</code>。<br />
时间复杂度O(nm),其中n和m为字符串a,b的长度。</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">package</span> <span class="nn">chapter2_String_Contains</span><span class="o">;</span>
<span class="cm">/**
* @Author: codefog
* @email: at20s@sina.com
* @Date: 2018/9/18 1:52 PM
*/</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">Solution1</span> <span class="o">{</span>
<span class="cm">/**
* 暴力轮询
*
* @param args
*/</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="nc">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
<span class="nc">String</span> <span class="n">a</span> <span class="o">=</span> <span class="s">"HelloWorld"</span><span class="o">;</span> <span class="c1">//j</span>
<span class="nc">String</span> <span class="n">b</span> <span class="o">=</span> <span class="s">"ldWor"</span><span class="o">;</span> <span class="c1">// i</span>
<span class="nc">String</span> <span class="n">c</span> <span class="o">=</span> <span class="s">"ABC"</span><span class="o">;</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">isContains1</span><span class="o">(</span><span class="n">a</span><span class="o">,</span> <span class="n">b</span><span class="o">));</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">isContains1</span><span class="o">(</span><span class="n">a</span><span class="o">,</span> <span class="n">c</span><span class="o">));</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">boolean</span> <span class="nf">isContains</span><span class="o">(</span><span class="nc">String</span> <span class="n">a</span><span class="o">,</span> <span class="nc">String</span> <span class="n">b</span><span class="o">)</span> <span class="o">{</span>
<span class="kt">char</span><span class="o">[]</span> <span class="n">aStr</span> <span class="o">=</span> <span class="n">a</span><span class="o">.</span><span class="na">toCharArray</span><span class="o">();</span>
<span class="kt">char</span><span class="o">[]</span> <span class="n">bStr</span> <span class="o">=</span> <span class="n">b</span><span class="o">.</span><span class="na">toCharArray</span><span class="o">();</span>
<span class="c1">//固定字符串b</span>
<span class="k">for</span> <span class="o">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span> <span class="n">i</span> <span class="o"><</span> <span class="n">bStr</span><span class="o">.</span><span class="na">length</span><span class="o">;</span> <span class="n">i</span><span class="o">++)</span> <span class="o">{</span>
<span class="kt">int</span> <span class="n">flag</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span>
<span class="k">for</span> <span class="o">(</span><span class="kt">int</span> <span class="n">j</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span> <span class="n">j</span> <span class="o"><</span> <span class="n">aStr</span><span class="o">.</span><span class="na">length</span><span class="o">;</span> <span class="n">j</span><span class="o">++)</span> <span class="o">{</span>
<span class="k">if</span> <span class="o">(</span><span class="n">bStr</span><span class="o">[</span><span class="n">i</span><span class="o">]</span> <span class="o">==</span> <span class="n">aStr</span><span class="o">[</span><span class="n">j</span><span class="o">])</span> <span class="o">{</span>
<span class="n">flag</span> <span class="o">=</span> <span class="mi">1</span><span class="o">;</span>
<span class="k">break</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="k">if</span> <span class="o">(</span><span class="n">flag</span> <span class="o">==</span> <span class="mi">0</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="k">return</span> <span class="kc">true</span><span class="o">;</span>
<span class="o">}</span>
<span class="cm">/**
* 相同算法,第二种写法
* @param a
* @param b
* @return
*/</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">boolean</span> <span class="nf">isContains1</span><span class="o">(</span><span class="nc">String</span> <span class="n">a</span><span class="o">,</span> <span class="nc">String</span> <span class="n">b</span><span class="o">)</span> <span class="o">{</span>
<span class="kt">char</span><span class="o">[]</span> <span class="n">aStr</span> <span class="o">=</span> <span class="n">a</span><span class="o">.</span><span class="na">toCharArray</span><span class="o">();</span>
<span class="kt">char</span><span class="o">[]</span> <span class="n">bStr</span> <span class="o">=</span> <span class="n">b</span><span class="o">.</span><span class="na">toCharArray</span><span class="o">();</span>
<span class="c1">//固定字符串b</span>
<span class="k">for</span> <span class="o">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span> <span class="n">i</span> <span class="o"><</span> <span class="n">bStr</span><span class="o">.</span><span class="na">length</span><span class="o">;</span> <span class="n">i</span><span class="o">++)</span> <span class="o">{</span>
<span class="k">for</span> <span class="o">(</span><span class="kt">int</span> <span class="n">j</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span> <span class="n">j</span> <span class="o"><</span> <span class="n">aStr</span><span class="o">.</span><span class="na">length</span><span class="o">;</span> <span class="n">j</span><span class="o">++)</span> <span class="o">{</span>
<span class="k">if</span> <span class="o">(</span><span class="n">bStr</span><span class="o">[</span><span class="n">i</span><span class="o">]</span> <span class="o">==</span> <span class="n">aStr</span><span class="o">[</span><span class="n">j</span><span class="o">])</span> <span class="o">{</span>
<span class="k">break</span><span class="o">;</span>
<span class="o">}</span>
<span class="c1">//字符串b移动到最后一位,a也是最后一位,仍然没有找到相同的,就返回false</span>
<span class="k">if</span> <span class="o">(</span><span class="n">bStr</span><span class="o">[</span><span class="n">i</span><span class="o">]</span> <span class="o">!=</span> <span class="n">aStr</span><span class="o">[</span><span class="n">j</span><span class="o">]</span> <span class="o">&&</span> <span class="n">i</span> <span class="o">==</span> <span class="n">bStr</span><span class="o">.</span><span class="na">length</span> <span class="o">-</span> <span class="mi">1</span> <span class="o">&&</span> <span class="n">j</span> <span class="o">==</span> <span class="n">aStr</span><span class="o">.</span><span class="na">length</span> <span class="o">-</span> <span class="mi">1</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="k">return</span> <span class="kc">true</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<h2 id="heading-解法2排序后再轮询">解法2,排序后再轮询</h2>
<p>排序时间复杂度<code class="highlighter-rouge">O(mlogm)+O(nlogn)+O(m+n)</code>,即两次排序和线性扫描的复杂度。与第一种解法类似,改进不大。</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">package</span> <span class="nn">chapter2_String_Contains</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.util.Arrays</span><span class="o">;</span>
<span class="cm">/**
* @Author: codefog
* @email: at20s@sina.com
* @Date: 2018/9/18 4:59 PM
*/</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">Solution2</span> <span class="o">{</span>
<span class="cm">/**
* 排序轮询
* @param args
*/</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="nc">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
<span class="nc">String</span> <span class="n">a</span> <span class="o">=</span> <span class="s">"HelloWorld"</span><span class="o">;</span> <span class="c1">//j</span>
<span class="nc">String</span> <span class="n">b</span> <span class="o">=</span> <span class="s">"ldWor"</span><span class="o">;</span> <span class="c1">// i</span>
<span class="nc">String</span> <span class="n">c</span> <span class="o">=</span> <span class="s">"ABC"</span><span class="o">;</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">isContains</span><span class="o">(</span><span class="n">a</span><span class="o">,</span> <span class="n">b</span><span class="o">));</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">isContains</span><span class="o">(</span><span class="n">a</span><span class="o">,</span> <span class="n">c</span><span class="o">));</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">boolean</span> <span class="nf">isContains</span><span class="o">(</span><span class="nc">String</span> <span class="n">a</span><span class="o">,</span> <span class="nc">String</span> <span class="n">b</span><span class="o">)</span> <span class="o">{</span>
<span class="kt">char</span><span class="o">[]</span> <span class="n">aStr</span> <span class="o">=</span> <span class="n">a</span><span class="o">.</span><span class="na">toCharArray</span><span class="o">();</span>
<span class="kt">char</span><span class="o">[]</span> <span class="n">bStr</span> <span class="o">=</span> <span class="n">b</span><span class="o">.</span><span class="na">toCharArray</span><span class="o">();</span>
<span class="nc">Arrays</span><span class="o">.</span><span class="na">sort</span><span class="o">(</span><span class="n">aStr</span><span class="o">);</span>
<span class="nc">Arrays</span><span class="o">.</span><span class="na">sort</span><span class="o">(</span><span class="n">bStr</span><span class="o">);</span>
<span class="c1">//固定字符串b</span>
<span class="k">for</span> <span class="o">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span> <span class="n">i</span> <span class="o"><</span> <span class="n">bStr</span><span class="o">.</span><span class="na">length</span><span class="o">;</span> <span class="n">i</span><span class="o">++)</span> <span class="o">{</span>
<span class="kt">int</span> <span class="n">flag</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span>
<span class="k">for</span> <span class="o">(</span><span class="kt">int</span> <span class="n">j</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span> <span class="n">j</span> <span class="o"><</span> <span class="n">aStr</span><span class="o">.</span><span class="na">length</span><span class="o">;</span> <span class="n">j</span><span class="o">++)</span> <span class="o">{</span>
<span class="k">if</span> <span class="o">(</span><span class="n">bStr</span><span class="o">[</span><span class="n">i</span><span class="o">]</span> <span class="o">==</span> <span class="n">aStr</span><span class="o">[</span><span class="n">j</span><span class="o">])</span> <span class="o">{</span>
<span class="n">flag</span> <span class="o">=</span> <span class="mi">1</span><span class="o">;</span>
<span class="k">break</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="k">if</span> <span class="o">(</span><span class="n">flag</span> <span class="o">==</span> <span class="mi">0</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="k">return</span> <span class="kc">true</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<h2 id="heading-解法3素数相乘">解法3,素数相乘</h2>
<p>时间复杂度O(m+n),最好情况O(n)。巧妙的利用了素数,非常聪明。缺点是获取的素数乘积会可能超过int的最大值,造成溢出。 <br />
证明: <code class="highlighter-rouge">每个正整数都可以唯一表示成素数的乘积.</code>在本算法中,利用字母在编码中对应的数字,可以把字母当作一个正整数,获取到他们的乘积后,可以为一表示字符串。</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>首先证明存在性,
用数学归纳法,n=2很显然,假设n<k时成立,当n=k时,如果k为素数,显然成立;如果k是合数,则至少有一个素因数p1,k=p1*a,而由归纳假设a<k能分解为素数乘积,所以n=k也成立.所以对于任意大于1的整数n都存在.
然后证明唯一性,
如果有两个分解式,2^p1*3^p2*5^p3*…=2^q1*3^q2*5^q3*…,则
2^p1|2^q1*3^q2*5^q3*…,所以p1≤q1,同理q1≤p1,所以p1=q1,
后边的类似证明.
</code></pre></div></div>
<p>代码:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">package</span> <span class="nn">chapter2_String_Contains</span><span class="o">;</span>
<span class="cm">/**
* @Author: codefog
* @email: at20s@sina.com
* @Date: 2018/9/18 10:33 PM
*/</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">Solution3</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="nc">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
<span class="nc">String</span> <span class="n">a</span> <span class="o">=</span> <span class="s">"HELLOWORLD"</span><span class="o">;</span> <span class="c1">//j</span>
<span class="nc">String</span> <span class="n">b</span> <span class="o">=</span> <span class="s">"LDWOR"</span><span class="o">;</span> <span class="c1">// i</span>
<span class="nc">String</span> <span class="n">c</span> <span class="o">=</span> <span class="s">"ABC"</span><span class="o">;</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">isContains</span><span class="o">(</span><span class="n">a</span><span class="o">,</span> <span class="n">b</span><span class="o">));</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">isContains</span><span class="o">(</span><span class="n">a</span><span class="o">,</span> <span class="n">c</span><span class="o">));</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">boolean</span> <span class="nf">isContains</span><span class="o">(</span><span class="nc">String</span> <span class="n">a</span><span class="o">,</span> <span class="nc">String</span> <span class="n">b</span><span class="o">)</span> <span class="o">{</span>
<span class="kd">final</span> <span class="kt">int</span><span class="o">[]</span> <span class="n">pr</span> <span class="o">=</span> <span class="o">{</span><span class="mi">2</span><span class="o">,</span><span class="mi">3</span><span class="o">,</span><span class="mi">5</span><span class="o">,</span><span class="mi">7</span><span class="o">,</span><span class="mi">11</span><span class="o">,</span><span class="mi">13</span><span class="o">,</span><span class="mi">17</span><span class="o">,</span><span class="mi">19</span><span class="o">,</span><span class="mi">23</span><span class="o">,</span><span class="mi">29</span><span class="o">,</span><span class="mi">31</span><span class="o">,</span><span class="mi">37</span><span class="o">,</span><span class="mi">41</span><span class="o">,</span><span class="mi">43</span><span class="o">,</span><span class="mi">47</span><span class="o">,</span><span class="mi">53</span><span class="o">,</span><span class="mi">59</span><span class="o">,</span><span class="mi">61</span><span class="o">,</span><span class="mi">67</span><span class="o">,</span><span class="mi">71</span><span class="o">,</span><span class="mi">73</span><span class="o">,</span><span class="mi">79</span><span class="o">,</span><span class="mi">83</span><span class="o">,</span><span class="mi">89</span><span class="o">,</span><span class="mi">97</span><span class="o">,</span><span class="mi">101</span><span class="o">};</span>
<span class="kt">long</span> <span class="n">muti</span> <span class="o">=</span> <span class="mi">1</span><span class="o">;</span>
<span class="kt">char</span><span class="o">[]</span> <span class="n">aStr</span> <span class="o">=</span> <span class="n">a</span><span class="o">.</span><span class="na">toCharArray</span><span class="o">();</span>
<span class="kt">char</span><span class="o">[]</span> <span class="n">bStr</span> <span class="o">=</span> <span class="n">b</span><span class="o">.</span><span class="na">toCharArray</span><span class="o">();</span>
<span class="c1">//遍历字符串a,获取到它所对应的全部素数的乘积</span>
<span class="k">for</span> <span class="o">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span> <span class="n">i</span> <span class="o"><</span> <span class="n">aStr</span><span class="o">.</span><span class="na">length</span><span class="o">;</span> <span class="n">i</span><span class="o">++)</span> <span class="o">{</span>
<span class="c1">//都是大写字母,所以直接相减就在26的范围内,即可确定索引值</span>
<span class="kt">int</span> <span class="n">index</span> <span class="o">=</span> <span class="n">aStr</span><span class="o">[</span><span class="n">i</span><span class="o">]</span> <span class="o">-</span> <span class="sc">'A'</span><span class="o">;</span>
<span class="n">muti</span> <span class="o">*=</span> <span class="n">pr</span><span class="o">[</span><span class="n">index</span><span class="o">];</span>
<span class="o">}</span>
<span class="c1">//遍历字符串b,然后让第一步获得的乘积和短字符串所对应的素数取余数,如果由余数,返回false</span>
<span class="k">for</span> <span class="o">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span> <span class="n">i</span> <span class="o"><</span> <span class="n">bStr</span><span class="o">.</span><span class="na">length</span><span class="o">;</span> <span class="n">i</span><span class="o">++)</span> <span class="o">{</span>
<span class="kt">int</span> <span class="n">index</span> <span class="o">=</span> <span class="n">bStr</span><span class="o">[</span><span class="n">i</span><span class="o">]</span> <span class="o">-</span> <span class="sc">'A'</span><span class="o">;</span>
<span class="k">if</span> <span class="o">(</span><span class="n">muti</span> <span class="o">%</span> <span class="n">pr</span><span class="o">[</span><span class="n">index</span><span class="o">]</span> <span class="o">></span> <span class="mi">0</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="k">return</span> <span class="kc">true</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<h2 id="heading-解法4位运算法hash">解法4,位运算法(HASH)</h2>
<p>这个方法和解法3类似,只不过把算出的素数乘积换成了HASH值,然后在用b查询,所有操作使用位运算完成。时间复杂度同上O(n+m),空间复杂度为O(1),对空间友好。</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">package</span> <span class="nn">chapter2_String_Contains</span><span class="o">;</span>
<span class="cm">/**
* @Author: codefog
* @email: at20s@sina.com
* @Date: 2018/9/19 12:06 AM
*/</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">Solution4</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="nc">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
<span class="nc">String</span> <span class="n">a</span> <span class="o">=</span> <span class="s">"HELLOWORLD"</span><span class="o">;</span> <span class="c1">//j</span>
<span class="nc">String</span> <span class="n">b</span> <span class="o">=</span> <span class="s">"LDWOR"</span><span class="o">;</span> <span class="c1">// i</span>
<span class="nc">String</span> <span class="n">c</span> <span class="o">=</span> <span class="s">"ABC"</span><span class="o">;</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">isContains</span><span class="o">(</span><span class="n">a</span><span class="o">,</span> <span class="n">b</span><span class="o">));</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">isContains</span><span class="o">(</span><span class="n">a</span><span class="o">,</span> <span class="n">c</span><span class="o">));</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">boolean</span> <span class="nf">isContains</span><span class="o">(</span><span class="nc">String</span> <span class="n">a</span><span class="o">,</span> <span class="nc">String</span> <span class="n">b</span><span class="o">)</span> <span class="o">{</span>
<span class="kt">char</span><span class="o">[]</span> <span class="n">aStr</span> <span class="o">=</span> <span class="n">a</span><span class="o">.</span><span class="na">toCharArray</span><span class="o">();</span>
<span class="kt">char</span><span class="o">[]</span> <span class="n">bStr</span> <span class="o">=</span> <span class="n">b</span><span class="o">.</span><span class="na">toCharArray</span><span class="o">();</span>
<span class="kt">int</span> <span class="no">HASH</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span>
<span class="c1">//遍历a字符串,为每个字符计算HASH值</span>
<span class="k">for</span> <span class="o">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span> <span class="n">i</span> <span class="o"><</span> <span class="n">aStr</span><span class="o">.</span><span class="na">length</span><span class="o">;</span> <span class="n">i</span><span class="o">++)</span> <span class="o">{</span>
<span class="no">HASH</span> <span class="o">|=</span> <span class="o">(</span><span class="mi">1</span> <span class="o"><<</span> <span class="o">(</span><span class="n">aStr</span><span class="o">[</span><span class="n">i</span><span class="o">]</span> <span class="o">-</span> <span class="sc">'A'</span><span class="o">));</span>
<span class="o">}</span>
<span class="c1">//把b的每个字符放到a中查找</span>
<span class="k">for</span> <span class="o">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span> <span class="n">i</span> <span class="o"><</span> <span class="n">bStr</span><span class="o">.</span><span class="na">length</span><span class="o">;</span> <span class="n">i</span><span class="o">++)</span> <span class="o">{</span>
<span class="k">if</span> <span class="o">(</span> <span class="o">(</span><span class="no">HASH</span> <span class="o">&</span> <span class="o">(</span><span class="mi">1</span> <span class="o"><<</span> <span class="o">(</span><span class="n">bStr</span><span class="o">[</span><span class="n">i</span><span class="o">]</span> <span class="o">-</span> <span class="sc">'A'</span><span class="o">))</span> <span class="o">)</span> <span class="o">==</span> <span class="mi">0</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="k">return</span> <span class="kc">true</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<h2 id="heading-其他资料算法">其他资料算法</h2>
<p>参考: <br />
https://www.cnblogs.com/tgycoder/p/5241157.html<br />
http://blog.jobbole.com/99205/</p>Rickyat20s@sina.com题目简介 给定一长字符串a -> ABCD,短字符串b -> BAD, 短字符串c -> BCE,则字符串b中的字母都在字符串a中,b是a的真子集,所以对于a,返回true,对于b,返回false,因为字符串b的元素E不在a中。 注意:都是大写字母算法 - 字符串旋转2018-09-17T00:00:00+00:002018-09-17T00:00:00+00:00https://tech.codefog.com/2018/algo-string-reverse<h2 id="heading-题目简介">题目简介</h2>
<p>字符串反转,字符串旋转,例如<code class="highlighter-rouge">abcdef</code>旋转为<code class="highlighter-rouge">defabc</code>。</p>
<h2 id="heading-解法1暴力">解法1,暴力</h2>
<p>时间复杂度<code class="highlighter-rouge">O(nm)</code>,空间<code class="highlighter-rouge">O(1)</code> (长度为n,移动m个字符)</p>
<h3 id="heading-坑">坑:</h3>
<p>java如果想覆盖字符串的值,不能和<code class="highlighter-rouge">c/c++</code>一样,直接传入指针就能修改原值,而是需要<code class="highlighter-rouge">old = opeartion(old)</code>这样子把旧的引用覆盖掉才行。</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">package</span> <span class="nn">string_reverse</span><span class="o">;</span>
<span class="cm">/**
* @Author: codefog
* @email: at20s@sina.com
* @Date: 2018/9/17 10:44 PM
*/</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">Solution1</span> <span class="o">{</span>
<span class="cm">/**
* 暴力一次一个字符的移动
* 时间复杂度O(nm),空间O(1) (长度为n,移动m个字符)
* @param args
*/</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="nc">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
<span class="nc">String</span> <span class="n">str</span> <span class="o">=</span> <span class="s">"hello world!"</span><span class="o">;</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">rotateString</span><span class="o">(</span><span class="n">str</span><span class="o">,</span><span class="mi">3</span><span class="o">));</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="nc">String</span> <span class="nf">shifting</span><span class="o">(</span><span class="nc">String</span> <span class="n">str</span><span class="o">)</span> <span class="o">{</span>
<span class="kt">char</span><span class="o">[]</span> <span class="n">strs</span> <span class="o">=</span> <span class="n">str</span><span class="o">.</span><span class="na">toCharArray</span><span class="o">();</span>
<span class="kt">char</span> <span class="n">temp</span> <span class="o">=</span> <span class="n">strs</span><span class="o">[</span><span class="mi">0</span><span class="o">];</span>
<span class="k">for</span> <span class="o">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">1</span><span class="o">;</span> <span class="n">i</span> <span class="o"><</span> <span class="n">strs</span><span class="o">.</span><span class="na">length</span><span class="o">;</span> <span class="o">++</span><span class="n">i</span><span class="o">)</span> <span class="o">{</span>
<span class="c1">//从第一个开始,一次被后一个字符覆盖</span>
<span class="n">strs</span><span class="o">[</span><span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="o">]</span> <span class="o">=</span> <span class="n">strs</span><span class="o">[</span><span class="n">i</span><span class="o">];</span>
<span class="o">}</span>
<span class="n">strs</span><span class="o">[</span><span class="n">strs</span><span class="o">.</span><span class="na">length</span> <span class="o">-</span> <span class="mi">1</span><span class="o">]</span> <span class="o">=</span> <span class="n">temp</span><span class="o">;</span>
<span class="k">return</span> <span class="nc">String</span><span class="o">.</span><span class="na">valueOf</span><span class="o">(</span><span class="n">strs</span><span class="o">);</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="nc">String</span> <span class="nf">rotateString</span><span class="o">(</span><span class="nc">String</span> <span class="n">string</span><span class="o">,</span> <span class="kt">int</span> <span class="n">m</span><span class="o">)</span> <span class="o">{</span>
<span class="k">while</span> <span class="o">(</span><span class="n">m</span> <span class="o">></span> <span class="mi">0</span><span class="o">)</span> <span class="o">{</span>
<span class="n">string</span> <span class="o">=</span> <span class="n">shifting</span><span class="o">(</span><span class="n">string</span><span class="o">);</span>
<span class="n">m</span><span class="o">--;</span>
<span class="o">}</span>
<span class="k">return</span> <span class="n">string</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<h2 id="heading-解法2三步反转">解法2,三步反转</h2>
<p>时间复杂度<code class="highlighter-rouge">O(n)</code>,空间复杂度<code class="highlighter-rouge">O(1)</code></p>
<ol>
<li>分割原字符串</li>
<li>分别反转</li>
<li>整体反转
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Solution2</span> <span class="o">{</span>
<span class="cm">/**
* 三步反转
* @param args
*/</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="nc">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
<span class="nc">String</span> <span class="n">str</span> <span class="o">=</span> <span class="s">"hello world!"</span><span class="o">;</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">rotateString</span><span class="o">(</span><span class="n">str</span><span class="o">,</span><span class="mi">4</span><span class="o">));</span>
<span class="o">}</span>
<span class="cm">/**
* 把字符串m到n的位置反转
* @param string
* @return
*/</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="nc">String</span> <span class="nf">reverseString</span><span class="o">(</span><span class="nc">String</span> <span class="n">string</span><span class="o">,</span><span class="kt">int</span> <span class="n">m</span><span class="o">,</span> <span class="kt">int</span> <span class="n">n</span><span class="o">)</span> <span class="o">{</span>
<span class="kt">char</span><span class="o">[]</span> <span class="n">cString</span> <span class="o">=</span> <span class="n">string</span><span class="o">.</span><span class="na">toCharArray</span><span class="o">();</span>
<span class="k">while</span> <span class="o">(</span><span class="n">m</span> <span class="o"><</span> <span class="n">n</span><span class="o">)</span> <span class="o">{</span>
<span class="kt">char</span> <span class="n">temp</span> <span class="o">=</span> <span class="n">cString</span><span class="o">[</span><span class="n">m</span><span class="o">];</span>
<span class="c1">//第一个值被最后一个覆盖,然后移动m到下一个值</span>
<span class="n">cString</span><span class="o">[</span><span class="n">m</span><span class="o">++]</span> <span class="o">=</span> <span class="n">cString</span><span class="o">[</span><span class="n">n</span><span class="o">];</span>
<span class="c1">//最后一个值被第一个覆盖,向前移动</span>
<span class="n">cString</span><span class="o">[</span><span class="n">n</span><span class="o">--]</span> <span class="o">=</span> <span class="n">temp</span><span class="o">;</span>
<span class="o">}</span>
<span class="k">return</span> <span class="nc">String</span><span class="o">.</span><span class="na">valueOf</span><span class="o">(</span><span class="n">cString</span><span class="o">);</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="nc">String</span> <span class="nf">rotateString</span><span class="o">(</span><span class="nc">String</span> <span class="n">str</span><span class="o">,</span> <span class="kt">int</span> <span class="n">m</span><span class="o">)</span> <span class="o">{</span>
<span class="c1">//m = m % length, 如果移动的位置数量超过长度,则相当于一个环旋转</span>
<span class="c1">// 3 % 5 = 3, 小于字符串长度则没有问题</span>
<span class="n">m</span> <span class="o">%=</span> <span class="n">str</span><span class="o">.</span><span class="na">length</span><span class="o">();</span>
<span class="c1">//反转第一部分</span>
<span class="n">str</span> <span class="o">=</span> <span class="n">reverseString</span><span class="o">(</span><span class="n">str</span><span class="o">,</span><span class="mi">0</span><span class="o">,</span> <span class="n">m</span><span class="o">);</span>
<span class="c1">//反转第二部分</span>
<span class="n">str</span> <span class="o">=</span> <span class="n">reverseString</span><span class="o">(</span><span class="n">str</span><span class="o">,</span> <span class="n">m</span><span class="o">,</span> <span class="n">str</span><span class="o">.</span><span class="na">length</span><span class="o">()</span> <span class="o">-</span> <span class="mi">1</span><span class="o">);</span>
<span class="c1">//整体反转</span>
<span class="n">str</span> <span class="o">=</span> <span class="n">reverseString</span><span class="o">(</span><span class="n">str</span><span class="o">,</span> <span class="mi">0</span><span class="o">,</span> <span class="n">str</span><span class="o">.</span><span class="na">length</span><span class="o">()</span> <span class="o">-</span> <span class="mi">1</span><span class="o">);</span>
<span class="k">return</span> <span class="n">str</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div> </div>
</li>
</ol>
<h2 id="heading-举一反三">举一反三</h2>
<p>反转句子中单词的位置,比如<code class="highlighter-rouge">i am a student.</code>, 反转后<code class="highlighter-rouge">student. a am i</code>,标点符号作为单词的一部分处理.</p>
<h3 id="heading-思路">思路</h3>
<ol>
<li>以空格分割句子为n(单词数量)部分</li>
<li>分别反转</li>
<li>总体反转</li>
</ol>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Others</span> <span class="o">{</span>
<span class="cm">/**
* 反转句子中的单词
* @param args
*/</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="nc">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
<span class="nc">String</span> <span class="n">str</span> <span class="o">=</span> <span class="s">"i am quite a student."</span><span class="o">;</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">rotateString</span><span class="o">(</span><span class="n">str</span><span class="o">));</span>
<span class="o">}</span>
<span class="cm">/**
* 把字符串m到n的位置反转
* @param string
* @return
*/</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="nc">String</span> <span class="nf">reverseString</span><span class="o">(</span><span class="nc">String</span> <span class="n">string</span><span class="o">,</span><span class="kt">int</span> <span class="n">m</span><span class="o">,</span> <span class="kt">int</span> <span class="n">n</span><span class="o">)</span> <span class="o">{</span>
<span class="kt">char</span><span class="o">[]</span> <span class="n">cString</span> <span class="o">=</span> <span class="n">string</span><span class="o">.</span><span class="na">toCharArray</span><span class="o">();</span>
<span class="k">while</span> <span class="o">(</span><span class="n">m</span> <span class="o"><</span> <span class="n">n</span><span class="o">)</span> <span class="o">{</span>
<span class="kt">char</span> <span class="n">temp</span> <span class="o">=</span> <span class="n">cString</span><span class="o">[</span><span class="n">m</span><span class="o">];</span>
<span class="c1">//第一个值被最后一个覆盖,然后移动m到下一个值</span>
<span class="n">cString</span><span class="o">[</span><span class="n">m</span><span class="o">++]</span> <span class="o">=</span> <span class="n">cString</span><span class="o">[</span><span class="n">n</span><span class="o">];</span>
<span class="c1">//最后一个值被第一个覆盖,向前移动</span>
<span class="n">cString</span><span class="o">[</span><span class="n">n</span><span class="o">--]</span> <span class="o">=</span> <span class="n">temp</span><span class="o">;</span>
<span class="o">}</span>
<span class="k">return</span> <span class="nc">String</span><span class="o">.</span><span class="na">valueOf</span><span class="o">(</span><span class="n">cString</span><span class="o">);</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="nc">String</span> <span class="nf">rotateString</span><span class="o">(</span><span class="nc">String</span> <span class="n">str</span><span class="o">)</span> <span class="o">{</span>
<span class="c1">//以空格分割,正则表达</span>
<span class="nc">String</span><span class="o">[]</span> <span class="n">spString</span> <span class="o">=</span> <span class="n">str</span><span class="o">.</span><span class="na">split</span><span class="o">(</span><span class="s">"\\s+"</span><span class="o">);</span>
<span class="n">str</span> <span class="o">=</span> <span class="s">""</span><span class="o">;</span>
<span class="c1">//分别反转分割后的字符串</span>
<span class="k">if</span> <span class="o">(</span><span class="n">spString</span><span class="o">.</span><span class="na">length</span> <span class="o">></span> <span class="mi">0</span><span class="o">)</span> <span class="o">{</span>
<span class="k">for</span> <span class="o">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span> <span class="n">i</span> <span class="o"><</span> <span class="n">spString</span><span class="o">.</span><span class="na">length</span><span class="o">;</span> <span class="o">++</span><span class="n">i</span><span class="o">)</span> <span class="o">{</span>
<span class="n">spString</span><span class="o">[</span><span class="n">i</span><span class="o">]</span> <span class="o">=</span> <span class="n">reverseString</span><span class="o">(</span><span class="n">spString</span><span class="o">[</span><span class="n">i</span><span class="o">],</span><span class="mi">0</span><span class="o">,</span><span class="n">spString</span><span class="o">[</span><span class="n">i</span><span class="o">].</span><span class="na">length</span><span class="o">()</span> <span class="o">-</span> <span class="mi">1</span><span class="o">);</span>
<span class="c1">//拼接完整字符串</span>
<span class="n">str</span> <span class="o">+=</span> <span class="s">" "</span> <span class="o">+</span> <span class="n">spString</span><span class="o">[</span><span class="n">i</span><span class="o">];</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="c1">//总体旋转</span>
<span class="n">str</span> <span class="o">=</span> <span class="n">reverseString</span><span class="o">(</span><span class="n">str</span><span class="o">,</span> <span class="mi">0</span><span class="o">,</span> <span class="n">str</span><span class="o">.</span><span class="na">length</span><span class="o">()</span> <span class="o">-</span> <span class="mi">1</span><span class="o">);</span>
<span class="k">return</span> <span class="n">str</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>复杂度同上.</p>Rickyat20s@sina.com题目简介 字符串反转,字符串旋转,例如abcdef旋转为defabc。解决Jenkins安装完成登陆后显示空白页面2018-08-28T00:00:00+00:002018-08-28T00:00:00+00:00https://tech.codefog.com/2018/Jenkins-after-login-blank-page<h2 id="heading-问题描述">问题描述</h2>
<p>随着上次解决Jenkins服务状态为<code class="highlighter-rouge">Active: active (exited)</code>的问题后,又遇到新的问题.<br />
再把Jenkins端口修改到80后,Jenkins的登录页面可以正常打开,但是一旦登录你的账号,就会显示空白页面,页面标题是<code class="highlighter-rouge">Jenkins wizard</code>,除非访问<code class="highlighter-rouge">http://jenkins.local/restart</code>或者其他URL带有后缀的页面才能显示东西,且功能正常.</p>
<h2 id="heading-问题解决">问题解决</h2>
<p>在网上寻找一番后,有人说是权限问题,但是我在Jenkins的<code class="highlighter-rouge">config.xml</code>中把权限禁用掉也无用,也有人说是插件冲突,同样,我直接禁用所有插件,一样没有效果. 最后有人提到是因为端口如果低于1000的话是会出现问题的,因为1000以内是系统服务或者其他软件的保留端口. 这一点我明白,可是我使用的就是web服务,80端口,道理上讲应该没问题. 最后我尝试把端口修改回<code class="highlighter-rouge">8080</code>后,Jenkins恢复正常,随即解决了问题,如果想使用80端口,可以用<code class="highlighter-rouge">Nginx反代</code>.</p>
<h2 id="heading-参考">参考</h2>
<p>https://www.youtube.com/watch?v=7DE_f3zX1RM</p>Rickyat20s@sina.com问题描述 随着上次解决Jenkins服务状态为Active: active (exited)的问题后,又遇到新的问题. 再把Jenkins端口修改到80后,Jenkins的登录页面可以正常打开,但是一旦登录你的账号,就会显示空白页面,页面标题是Jenkins wizard,除非访问http://jenkins.local/restart或者其他URL带有后缀的页面才能显示东西,且功能正常.解决Nginx反代80端口出现502错误2018-08-28T00:00:00+00:002018-08-28T00:00:00+00:00https://tech.codefog.com/2018/nginx-reverse-proxy-502<h2 id="heading-问题描述">问题描述</h2>
<p>在上一篇博文中提到,我准备用<code class="highlighter-rouge">Nginx反代</code>来实现Jenkins的80端口访问,但是在我设置好反代后,访问80端口,却出现了502错误.<code class="highlighter-rouge">Nginx</code>安装方式使用<code class="highlighter-rouge">yum install nginx</code>的方式安装, 我的反代配置文件如下:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>server {
listen 80;
server_name jenkins.local;
#access_log /var/log/jenkins_access_log main;
#error_log /var/log/jenkins_error_log debug_http;
client_max_body_size 60M;
client_body_buffer_size 512k;
location / {
proxy_pass http://localhost:8080;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
</code></pre></div></div>
<p>可以看到应该是没有任何问题的,<code class="highlighter-rouge">reload</code>Nginx也没有报错,经过查看Nginx日志文件<code class="highlighter-rouge">/var/log/nginx/error.log</code>,发现Nginx爆出如下权限问题:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>2018/08/28 22:52:49 [error] 13213#0: *8 no live upstreams while connecting to upstream, client: 10.0.0.1, server: jenkins.local, request: "GET / HTTP/1.1", upstream: "http://localhost/", host: "jenkins.local"
</code></pre></div></div>
<p>经过搜索,发现有个博主给出了关闭<code class="highlighter-rouge">SELinux</code>的解决方案,尝试后问题成功解决.使用命令<code class="highlighter-rouge"> getsebool -a |grep httpd_can_network_connect </code>查看返回结果<code class="highlighter-rouge">httpd_can_network_connect --> off</code>发现httpd无网络权限,
<code class="highlighter-rouge">setsebool -P httpd_can_network_connect 1 </code>开启权限.<br />
有关<code class="highlighter-rouge">SELinux</code>请自行谷歌百度,它是个Linux的安全子系统.</p>
<h2 id="heading-参考">参考</h2>
<p>http://blog.codingplayboy.com/2017/05/22/nginx-502-bad-gateway/</p>Rickyat20s@sina.com问题描述 在上一篇博文中提到,我准备用Nginx反代来实现Jenkins的80端口访问,但是在我设置好反代后,访问80端口,却出现了502错误.Nginx安装方式使用yum install nginx的方式安装, 我的反代配置文件如下: ``` server {Centos7启动Jenkins服务状态Active: active (exited)的问题解决2018-08-27T00:00:00+00:002018-08-27T00:00:00+00:00https://tech.codefog.com/2018/jenkins-exist-problem<h2 id="heading-问题描述">问题描述</h2>
<p>因为需要准备Kale项目, 所以在本地的VMware中部署了一套测试环境和持续构建. 其中CI选定的是Jenkins. 我使用的是<code class="highlighter-rouge">Centos1804</code>版本,是博文发表时候的最新版本,安装Jenkins直接使用<code class="highlighter-rouge">yum</code>来安装,JDK版本为<code class="highlighter-rouge">OpenJDK1.8</code>.<br />
安装完成后,添加到服务并且设置开机启动,我在本地设置了host,所以不需要使用<code class="highlighter-rouge">8080</code>端口访问Jenkins,所以我在<code class="highlighter-rouge">/etc/sysconfig/jenkins</code>中修改端口号为<code class="highlighter-rouge">80</code>, 之后使用<code class="highlighter-rouge">systemctl restart jenkins</code>重启Jenkins,发现重启命令不报错,但是服务运行状态为<code class="highlighter-rouge">Active: active (exited)</code>.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[root@jenkins ~]# systemctl status jenkins
● jenkins.service - LSB: Jenkins Automation Server
Loaded: loaded (/etc/rc.d/init.d/jenkins; bad; vendor preset: disabled)
Active: active (exited) since Sun 2018-08-26 23:03:42 CST; 2h 14min ago
Docs: man:systemd-sysv-generator(8)
Process: 986 ExecStart=/etc/rc.d/init.d/jenkins start (code=exited, status=0/SUCCESS)
CGroup: /system.slice/jenkins.service
└─1387 /etc/alternatives/java -Dcom.sun.akuma.Daemon=daemonized -Djava.awt.headless=true ...
Aug 26 23:03:41 jenkins.local systemd[1]: Starting LSB: Jenkins Automation Server...
Aug 26 23:03:41 jenkins.local runuser[1007]: pam_unix(runuser:session): session opened for user r...=0)
Aug 26 23:03:42 jenkins.local jenkins[986]: Starting Jenkins [ OK ]
Aug 26 23:03:42 jenkins.local systemd[1]: Started LSB: Jenkins Automation Server.
Hint: Some lines were ellipsized, use -l to show in full.
</code></pre></div></div>
<h2 id="heading-问题解决">问题解决</h2>
<p>随后在google上寻找一番无果,终于在配置文件中看到如下:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code># Unix user account that runs the Jenkins daemon
# Be careful when you change this, as you need to update
# permissions of $JENKINS_HOME and /var/log/jenkins.
#
JENKINS_USER="jenkins"
</code></pre></div></div>
<p><strong>在修改过配置文件后,需要重新设定相应的权限Jenkins才可以正常运行</strong>,于是修改<code class="highlighter-rouge">JENKINS_USER="jenkins"</code>为<code class="highlighter-rouge">root</code>后,问题得到解决.</p>Rickyat20s@sina.com问题描述 因为需要准备Kale项目, 所以在本地的VMware中部署了一套测试环境和持续构建. 其中CI选定的是Jenkins. 我使用的是Centos1804版本,是博文发表时候的最新版本,安装Jenkins直接使用yum来安装,JDK版本为OpenJDK1.8. 安装完成后,添加到服务并且设置开机启动,我在本地设置了host,所以不需要使用8080端口访问Jenkins,所以我在/etc/sysconfig/jenkins中修改端口号为80, 之后使用systemctl restart jenkins重启Jenkins,发现重启命令不报错,但是服务运行状态为Active: active (exited). ``` [root@jenkins ~]# systemctl status jenkins ● jenkins.service - LSB: Jenkins Automation Server Loaded: loaded (/etc/rc.d/init.d/jenkins; bad; vendor preset: disabled) Active: active (exited) since Sun 2018-08-26 23:03:42 CST; 2h 14min ago Docs: man:systemd-sysv-generator(8) Process: 986 ExecStart=/etc/rc.d/init.d/jenkins start (code=exited, status=0/SUCCESS) CGroup: /system.slice/jenkins.service └─1387 /etc/alternatives/java -Dcom.sun.akuma.Daemon=daemonized -Djava.awt.headless=true …