cenos7+openssh 修改SSH服务端口

环境: cenos7(X86_64) + openssh ssh端口配置 修改端口 例如8888 文件 /etc/ssh/sshd_config #Port 22 Port 8888 重启服务 systemctl restart sshd systemctl status sshd 防火墙配置: 我这里配置比较简单仅zone配置了一个public firewall-cmd --permanent --zone=public --add-port=8888/tcp 重启服务 systemctl restart firewalld systemctl status firewalld

2020-07-13 · 1 min · 33 words

LeetCode – Path Sum Solution

题目: Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum. Note: A leaf is a node with no children. Example: Given the below binary tree and sum = 22, 5 / \ 4 8 / / \ 11 13 4 / \ \ 7 2 1 return true, as there exist a root-to-leaf path 5->4->11->2 which sum is 22. ...

2020-07-12 · 1 min · 205 words

LeetCode – Symmetric Tree Solution

题目: Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). For example, this binary tree [1,2,2,3,4,4,3] is symmetric: 1 / \ 2 2 / \ / \ 3 4 4 3 But the following [1,2,2,null,3,null,3] is not: 1 / \ 2 2 \ \ 3 3 Follow up: Solve it both recursively and iteratively. 实现: 递归方式, 判断左子树的左节点和右子树右节点值是否相等, 判断左子树的右节点和右子树左节点值是否相等 空间复杂度O(N) 时间复杂度 O(N) class Solution { public boolean isSymmetric(TreeNode root) { if (root == null) { return true; } return helper(root.left, root.right); } public boolean helper(TreeNode l, TreeNode r){ if (l == null && r == null){ return true; } else if (l == null || r == null){ return false; } return (l.val == r.val) && helper(l.right, r.left) && helper(l.left, r.right); } } 迭代方式,按照左子树右节点,左节点,右子树的左节点, 右节点,就是每层要比较的顺序, 分别放入各自队列, 再同时弹出队列, 由于不是满二叉树, 每层有空的情况, 所以如果出队列节点全为空,需要继续。 空间复杂度O(N) 时间复杂度 O(N) class Solution { public boolean isSymmetric(TreeNode root) { if (root == null){ return true; } Queue<TreeNode> ql = new LinkedList<>(); Queue<TreeNode> qr = new LinkedList<>(); ql.offer(root.left); qr.offer(root.right); while (!ql.isEmpty() && !qr.isEmpty()){ TreeNode lnode = ql.poll(); TreeNode rnode = qr.poll(); if (lnode == null && rnode == null){ continue; } else if (lnode == null || rnode == null){ return false; } else if (lnode.val != rnode.val){ return false; } ql.offer(lnode.left); ql.offer(lnode.right); qr.offer(rnode.right); qr.offer(rnode.left); } return true; } }

2020-07-12 · 2 min · 218 words

Linux slob/slab/slub

概述 Linux初始化通过bootmem/memblock引导内存分配进行内存管理,支持buddy system完成相关初始化后,将物理内存分配的功能转交给buddy system,buddy system是以page为单位分配方式。 对于内核要经常创建的对象, 如task_struct,fs_struct, mm_struct 通常会放到高速缓存中,保留基本结构,从而可以重复使用他们, 这里需要用到slab分配器。 slab分配器 通过 buddy system 申请空闲页 将申请到页处理为更小的分配单元,为其他子系统提供缓冲区存放内核对象 缓存经常使用的对象,释放后保存器初始状态,再次分配对象速度会很快 充分利用硬件高速缓存 历史发展 1991 Initial K&R allocator 1996 SLAB allocator 2003 SLOB allocator 2004 NUMA SLAB 2007 SLUB allocator 2008 SLOB mulitlist 2011 SLUB fastpath rework 2013 Common slab code 2014 SLUBification of SLAB … 常用的分配器 SLOB: K&R allocator (1991-1999) SLAB: Solaris type allocator (1999-2008) SLUB: Unqueued allocator (2008-today SLOB 简单的空闲对象列表管理 遍历列表查找合适的空间,没有的话申请向伙伴系统申请page增加堆栈大小. 碎片化严重 优化: 按照不同大小多个链表,减少碎片。 原理图 ...

2020-07-11 · 6 min · 1207 words

为什么x86无法生存-Why x86 won’t survive

前不久, 评估CEO 库克在其全球开发者大宣布,Mac笔记本以及个人电脑将会改用苹果自家的ARM架构处理器。这将是自2006年从PowerPC处理器改用英特尔x86处理器后,又一次CPU架构的调整。下面这篇文章是Medium推送的,不过文章贬低X86中提到的漏洞, 我查了资料其实部分ARM也是存在的。 不过确实是代表了一类观点。 苹果的去INTEL,让我想起了去IOE. 原文链接 Why x86 won’t survive X86是Intel公司1978年发明的一种微处理架构,他应用于大多数笔记本。他被认为是高效的, 可靠的, 直到前一段时间, 2018年发现的一系列漏洞 x86是由Intel创建的微体系结构(是一套开发处理器的指令集架构),最早在1978年面市(Intel 8086)。它为大多数笔记本电脑所采用,并且可能为您现在使用的笔记本电脑使用的就是这一系列的CPU。 直到几个月前,它才被认为是强大,有效和可靠的。 仅在2018年发现的x86体系结构中存在的漏洞和漏洞利用的简短历史记录: Meltdown, Spectre, SMT/Hyper threading found to be a security threat. 好像不是很多? 实际不是这样的。这3个漏洞是最近历史上发现的最主要的漏洞,几乎影响了所有笔记本电脑,台式机和服务器内核。 虽然已针对前两个实施了修复程序,但主要缺点是性能命中率高达15%。 在修复Spectre和Meltdown后不久,SMT/Hyper 已显示出使Intel和AMD CPU上的预测执行缺陷变得更糟。 具有古老而混乱的指令集的x86开始显示它的年龄,并且无法做它曾经可以做的事情。 什么是Speculative Execution?为什么要有它? 这就是ARM的用武之地。ARM出现于1990年(wiki上显示是1983年艾康电脑公司开始设计),是通常用于移动电话的台式机处理器的更新且更轻量的替代品。 如今,大多数智能手机都使用基于ARM的处理器,例如高通的Snapdragon系列,麒麟和苹果的定制7nm A系列处理器。 它们重量轻,功能强大且效率极高。 这些处理器比几年前的某些高端游戏台式机更好,但是它们有一个主要缺点-这就是为什么它们从未在笔记本电脑中使用过的原因。 应用程序兼容性。 几乎每个应用程序都是专门为x86开发的,没有考虑ARM的余地。 但是,这种情况开始有所改变。 谷歌正在帮助高通和微软将其浏览器引入ARM架构的Windows设备。 这是一个缓慢的开始,但这标志着x86结束的开始。 Google 已经看到ARM的发展空间, 苹果和微软也如此,如果他们开始致力于做好ARM兼容性, 那么大多数开发者将效仿并为此架构发布自己的软件, 随着兼容性的增加, 由于速度, 可靠性,安全性和价格原因,更多的用户切换到ARM, 由于X86的明显的漏洞, 更多的人将选择ARM. 当然,这种情况不会在一到两年内发生,但最终会发生。 这将是x86的终结,如果没有它,我们可能会更好。

2020-06-29 · 1 min · 59 words

通过alternatives进行多版本间切换

上周在学习单点登录安装CAS Overlay Template要使用指定版本,当时机器上安装了多个版本的jdk使用alternatives命令进行了切换. 如果需要在多个版本应用间切换并进行管理可以使用这个命令。 alternative 前身是 Debian Linux的一个用 Perl实现的工具 update-alternatives 后续Red Hat重写了并重新命名使用在 Red Hatand CentOS版本中. alternative统一了有多个版本应用,但在UNIX中更认可通过环境变量来设置 通常定义在 /etc/profile 或 $HOME/.profile 下面用一个例子演示一下 如果有有一个应用 em ,他的新版本 nem, 由于习惯原因, 我们更习惯敲em, 可以通过下面步骤设置一下 创建 先创建两个脚本做为代表em nem应用 [root@centosgpt alternatives]# cat em #!/bin/bash echo " This is em " [root@centosgpt alternatives]# cat nem #!/bin/bash echo " This is nem " 生成一个alternative需要下面四个要素: alternatives --install <link> <name> <path> <priority> link : 统一应用名称,一个链接文件 name : alternative 的名称便于记忆 path : 实际版本的路径 priority :优先级 [root@centosgpt alternatives]# sudo alternatives --install /usr/bin/em uemacs /root/alternatives/em 1 [root@centosgpt alternatives]# sudo alternatives --install /usr/bin/em uemacs /root/alternatives/nem 99 [root@centosgpt alternatives]# alternatives --config uemacs There are 2 programs which provide 'uemacs'. Selection Command ----------------------------------------------- + 1 /root/alternatives/em * 2 /root/alternatives/nem 验证 [root@centosgpt ~]# em This is nem [root@centosgpt ~]# alternatives --config uemacs There are 2 programs which provide &#039;uemacs&#039;. Selection Command ----------------------------------------------- 1 /root/alternatives/em *+ 2 /root/alternatives/nem Enter to keep the current selection[+], or type selection number: 1 [root@centosgpt ~]# em This is em 移除 alternatives --remove <name> <path> ...

2020-06-28 · 2 min · 324 words

LeetCode – Maximum Depth of Binary Tree

题目: Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node. Note: A leaf is a node with no children. Example: Given binary tree [3,9,20,null,null,15,7], 3 / \ 9 20 / \ 15 7 return its depth = 3. 解题: 深度优先搜索方式,分别找到左右子树最大的深度+1即可;广度优先搜索,逐层遍历找到最大层数返回。 实现 DFS, 空间复杂度O(N) 时间复杂度 O(N) /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ class Solution { public: int maxDepth(TreeNode* root) { if (!root) {return 0;} return 1 + max( maxDepth(root->left), maxDepth(root->right)); } }; 实现: BFS 空间复杂度O(N) 时间复杂度 O(N) /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ /* class Solution { public: int maxDepth(TreeNode* root) { if (!root) {return 0;} return 1 + max( maxDepth(root->left), maxDepth(root->right)); } };*/ class Solution { public: int maxDepth(TreeNode* root) { if (!root){ return 0; } queue<TreeNode*> q; int depth=0; q.push(root); while(!q.empty()){ depth ++; int level_size = q.size(); for (int i=0; i<level_size; i++){ TreeNode *node = q.front(); q.pop(); if (node->left){ q.push(node->left); } if (node->right){ q.push(node->right); } } } return depth; } };

2020-06-23 · 2 min · 263 words

LeetCode – Minimum Depth of Binary Tree

题目: Given a binary tree, find its minimum depth. The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node. Note: A leaf is a node with no children. Example: Given binary tree [3,9,20,null,null,15,7], 3 / \ 9 20 / \ 15 7 return its minimum depth = 2. 解题: 深度优先搜索方式,分别找到左右子树最小+1;广度优先搜索,逐层遍历找到叶子节点返回层数。 实现: DFS 空间复杂度O(N) 时间复杂度 O(N) class Solution { public: int minDepth(TreeNode* root) { if(!root) return 0; if(!root->left) return 1+minDepth(root->right); if(!root->right) return 1+minDepth(root->left); return 1+min(minDepth(root->left), minDepth(root->right)); } }; 实现: BFS 空间复杂度O(N) 时间复杂度 O(N) /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ class Solution { public: int minDepth(TreeNode* root) { if (!root){ return 0; } int depth = 0; queue<TreeNode *> q; q.push(root); while(!q.empty()){ depth++; int level_size = q.size(); for(int i=0; i<level_size; i++){ TreeNode *node = q.front(); q.pop(); if (!node->left&&!node->right){ return depth; } if (node->left){ q.push(node->left); } if (node->right){ q.push(node->right); } } } return depth; } };

2020-06-23 · 1 min · 200 words

Linux Swap 启停及swappiness设置

生成swap分区 可以通过磁盘分区和文件两种方式进行操作 1. 通过磁盘分区 划出一块4G磁盘fdisk /dev/sdb sdb磁盘对应的文件 [root@centosgpt ~]# fdisk /dev/sdb Command (m for help): n Partition number (1-128, default 1): First sector (34-41943006, default 2048): Last sector, +sectors or +size{K,M,G,T,P} (2048-41943006, default 41943006): +4G Created partition 1 ... Command (m for help): p ... # Start End Size Type Name 1 2048 8390655 4G Linux filesyste .. Command (m for help): w The partition table has been altered! 创建分区mkswap /dev/sdb1 sdb1对应分区 [root@centosgpt ~]# mkswap /dev/sdb1 Setting up swapspace version 1, size = 1020 KiB no label, UUID=5dabc5b1-d763-4757-9e0c-383f0cacb0ea 2. 通过文件生成 生成文件dd if=/dev/zero of=/swap bs=1MB count=1024 ...

2020-06-21 · 2 min · 344 words

The XY Problem

The XY Problem 原文链接 The XY Problem 什么是XY问题 XY问题是在询问您尝试的解决方案,而不是您的实际问题。 这导致提问者和回答者大量的时间和精力浪费。 用户想做X。 用户不知道如何做X,但认为只要能够做Y,他们就可以找到解决方案。 用户也不知道该怎么做Y。 用户请求有关Y的帮助。 其他人试图用Y帮助用户,但感到困惑,因为Y似乎是一个很想解决的问题。 经过大量的交互和浪费的时间之后,终于可以清楚地知道用户确实需要X的帮助,而Y甚至不是X的合适解决方案。 当人们陷于他们所认为的相关解决方案无法及进行,停下来并完整地解释问题时,就会出现问题。 如何解决 始终包括有关更广泛情况的信息以及任何尝试的解决方案。 如果有人要求提供更多信息,请提供详细信息。 如果您已经排除了其他解决方案,请分享您排除它们的原因。 这将提供有关您的问题的更多信息。 记住,如果您的诊断理论是正确的,您就不会寻求帮助了 例子 Example 1 n00b实际上并不需要文件名中的最后3个字符,而是想要文件扩展名,那么为什么要问最后3个字符呢? <n00b>如何回显文件名中的最后三个字符? <feline>如果它们在变量中:echo $ {foo:-3} <feline>为什么要输入3个字符? 你真正想要的是什么? <feline>您是否需要扩展名? <n00b>是。 <feline>不能保证每个文件名都具有三个字母的扩展名, <feline>所以盲目地抓三个字符并不能解决问题。 <feline> echo $ {foo ## *。} Example 2 如果Angela刚开始解释说她想防止其他人检测到她的操作系统,那本来可以是简短得多且更有成果的讨论。 Angela:'nmap -O -A 127.0.0.1'返回以'OS:'开头的某些行。 怎么改变呢? Obama:在nmap的源代码中查找,找到如何找到Linux部分,然后重写TCP / IP堆栈以使nmap无法检测到它。 Angela:是的,但是我完全不了解linux系统api。 Obama:好吧,nmap基于TCP / IP堆栈的工作方式,除了重写该堆栈的适当部分外,没有真正的方法。 Angela:我真的需要避免这些信息。 iptables可以完成这项工作吗? Obama:好吧,不要使用操作系统检测或版本扫描 Angela:我想防止其他人知道我的操作系统类型

2020-06-21 · 1 min · 62 words