查看inode相关信息

inode定义 The inode (index node) is a data structure in a Unix-style file system that describes a file-system object such as a file or a directory. Each inode stores the attributes and disk block locations of the object's data. File-system object attributes may include metadata (times of last change,[2] access, modification), as well as owner and permission data.[3] from inode wiki inode数据结构用于描述文件系统中的文件、目录等, 每一个inode保存了文件系统系统对象memdata如修改时间,访问时间以及权限等。Dennis Ritchie对于inode中i可能代表index,而被访问的文件列表,被组织为存放存放在磁盘上的一维数组。 环境准备 Linux Distributions: CentOS 7 通过fdisk划出一个10M分区, 格式化为ext4 $ fdisk /dev/sdb ... # Start End Size Type Name 1 2048 8390655 4G Linux filesyste 2 8390656 8411135 10M Linux filesyste [root@centosgpt ~]# $ mkfs.ext4 /dev/sdb2 $ mount /dev/sdb2 /root/inode inode查看 ls ls -i 文件名or目录 ...

2020-09-15 · 2 min · 257 words

close-on-exec

简介 Donald E. Porter 教授的 CSE 506: Operating Systems 教材 VFS 部分中提到Linux文件操作使用的一个标识 CLOSE_ON_EXEC – a bit that prevents file inheritance if a new binary is exec’ed (set by open or fcntl) 这个标识位支持exec执行前关闭其从父进程继承来的文件描述符 使用 设置方法: 通过fcntl 设置FD_CLOEXEC int flags = fcntl(connfd, F_GETFD); flags |= FD_CLOEXEC; fcntl(connfd, F_SETFD, flags); 通过O_CLOEXEC open(path, O_CLOEXEC | flags) socket(DOMAIN, SOCK_CLOEXEC | type, PROTOCOL) accept4(int sockfd, struct sockaddr *addr, \ socklen_t *addrlen, SOCK_CLOEXEC | flags); fopen(path, "re") 可以在以下这种模式下使用, fork后还是dup了父进程的文件描述符,exec后将自动关闭. pid_t pid; pid = fork(); if (pid == 0) { exec(...) }; 验证 代码 server.c ...

2020-09-09 · 3 min · 526 words

LeetCode – Populating Next Right Pointers in Each Node Solution

题目: You are given a perfect binary tree where all leaves are on the same level, and every parent has two children. The binary tree has the following definition: struct Node { int val; Node *left; Node *right; Node *next; } Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to NULL. Initially, all next pointers are set to NULL. ...

2020-09-07 · 2 min · 413 words

LeetCode –Populating Next Right Pointers in Each Node II

题目: Given a binary tree struct Node { int val; Node *left; Node *right; Node *next; } Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to NULL. Initially, all next pointers are set to NULL. Follow up: You may only use constant extra space. Recursive approach is fine, you may assume implicit stack space does not count as extra space for this problem. Example 1: ...

2020-09-07 · 2 min · 418 words

LeetCode- Implement Trie (Prefix Tree)

题目: Implement a trie with insert, search, and startsWith methods. Example: Trie trie = new Trie(); trie.insert("apple"); trie.search("apple"); // returns true trie.search("app"); // returns false trie.startsWith("app"); // returns true trie.insert("app"); trie.search("app"); // returns true Note: You may assume that all inputs are consist of lowercase letters a-z. All inputs are guaranteed to be non-empty strings. 实现: TrieTree是一个多叉树,是解决字符串快速匹配问题的数据结构, 他用于存储一个字符串,每个TrieTree的节点代表一个字符串/字符串前缀,每个节点可以有多个孩子节点,指向不同子节点不同路径代表不同的字符串,子节点的字符串是由本子节点的字符加上从根节点到本节点路径上的字符组成。 本地实现上, 节点的子节点使用数组或哈希表存储,只处理26个字母,通过判断子节点指针是否为空判断该字符是否存在。 具体实现参考leetcode提供的伪代码 使用数组版本 class Trie { private: #define N 26 struct TrieNode { TrieNode* children[N]; bool bEnd=false; }; TrieNode *root; public: /** Initialize your data structure here. */ Trie() { root = new TrieNode; for (int i=0; i<N; i++){ root->children[i]= nullptr; } } /** Inserts a word into the trie. */ void insert(string word) { /* 1. Initialize: cur = root 2. for each char c in target string S: 3. if cur does not have a child c: 4. cur.children[c] = new Trie node 5. cur = cur.children[c] 6. cur is the node which represents the string S */ // Return a specific child node with char c: (root->children)[c - 'a'] TrieNode *cur = root; for(char& c : word) { if (cur->children[c - 'a'] == nullptr){ cur->children[c - 'a'] = new TrieNode(); } cur = cur->children[c - 'a']; } cur->bEnd = true; } /** Returns if the word is in the trie. */ bool search(string word) { /*1. Initialize: cur = root 2. for each char c in target string S: 3. if cur does not have a child c: 4. search fails 5. cur = cur.children[c] 6. search successes */ TrieNode *cur = root; for(char& c : word) { if (cur->children[c - 'a'] == nullptr){ return false; } cur = cur->children[c - 'a']; } if (cur->bEnd) return true; else return false; } /** Returns if there is any word in the trie that starts with the given prefix. */ bool startsWith(string prefix) { /*1. Initialize: cur = root 2. for each char c in target string S: 3. if cur does not have a child c: 4. search fails 5. cur = cur.children[c] 6. search successes */ TrieNode *cur = root; for(char& c : prefix) { if (cur->children[c - 'a'] == nullptr){ return false; } cur = cur->children[c - 'a']; } return true; } }; /** * Your Trie object will be instantiated and called as such: * Trie* obj = new Trie(); * obj->insert(word); * bool param_2 = obj->search(word); * bool param_3 = obj->startsWith(prefix); */ 使用hash表实现 class Trie { private: #define N 26 struct TrieNode { unordered_map<char, TrieNode*> children; bool bEnd=false; }; TrieNode *root; public: /** Initialize your data structure here. */ Trie() { root = new TrieNode; for (int i=0; i<N; i++){ ( root->children)[i]= nullptr; } } /** Inserts a word into the trie. */ void insert(string word) { /* 1. Initialize: cur = root 2. for each char c in target string S: 3. if cur does not have a child c: 4. cur.children[c] = new Trie node 5. cur = cur.children[c] 6. cur is the node which represents the string S */ // unordered_map char c: (root->children)[c] TrieNode *cur = root; for(char& c : word) { if ((cur->children)[c] == nullptr){ (cur->children)[c] = new TrieNode(); } cur = (cur->children)[c]; } cur->bEnd = true; } /** Returns if the word is in the trie. */ bool search(string word) { /*1. Initialize: cur = root 2. for each char c in target string S: 3. if cur does not have a child c: 4. search fails 5. cur = cur.children[c] 6. search successes */ TrieNode *cur = root; for(char& c : word) { if ((cur->children)[c] == nullptr){ return false; } cur = (cur->children)[c]; } if (cur->bEnd) return true; else return false; } /** Returns if there is any word in the trie that starts with the given prefix. */ bool startsWith(string prefix) { /*1. Initialize: cur = root 2. for each char c in target string S: 3. if cur does not have a child c: 4. search fails 5. cur = cur.children[c] 6. search successes */ TrieNode *cur = root; for(char& c : prefix) { if ((cur->children)[c] == nullptr){ return false; } cur = (cur->children)[c]; } return true; } }; /** * Your Trie object will be instantiated and called as such: * Trie* obj = new Trie(); * obj->insert(word); * bool param_2 = obj->search(word); * bool param_3 = obj->startsWith(prefix); */ 参考: https://leetcode.com/problems/implement-trie-prefix-tree/solution/

2020-09-03 · 4 min · 716 words

MezzFS文件系统

这篇文章MezzFS — Mounting object storage in Netflix’s media processing platfor 是出自medium Netflix Technology Blog,作者 Barak Alon MezzFS: Mezzanine文件系统的缩写, 是Netflix使用Python开发的一个工具,可通过FUSE将云对象作为本地文件挂载。 FUSE支持用户态空间的文件系统, 文件操作命令通过VFS->FUSE->glibc->libfuse->用户自定义文件系统实现, 从而可以在用户态重新定义文件操作. Netflix处理视频编码主要涉及以下几个方面问题: 针对不同编码器分辨率进行多次编码,如果编码技术更新调整 可能需要全部重新编码 文件拆分并加密为单独的块,并将这些块存储在Amazon S3中。另外需要处理内容安全性,审核,灾难恢复等 视频编码器都是处理本地文件系统上的文件,不会去调用API去处理云上文件。视频文件非常大,需要避免为了处理一小块而下载整个视频文件 MezzFS的一些特点; Stream objects: 流对象不要外设存储 Assemble and decrypt parts: MezzFS知道如何组装和解密 Mount multiple objects: 挂载多个对象 Disk Caching: 支持本地磁盘缓冲 Mount ranges of objects: 可以将云对象指定范围对象挂载到本地 Regional caching: 一个区域的缓冲信息可以被另一个区域使用 关键特征replay; 支持配置MezzFS为记录replay文件。 该文件包括: 元数据, 文件操作, 缓存的内容, 统计信息。有这些信息可以实现可视化的功能, 可以用来调试错误,进行性能分析. 关键特征Adaptive Buffer; 由于使用FUSE系统, 内核将分块读入, 这意味这1G 的挂载文件, MezzFS可能要针对64KB块进行16384次读取。 因此最好可以预先读取一大块进行缓存。但是由于涉及离散和连续数据, 因此出现了Adaptive Buffer 具体公式数据来源于最近的读取的信息. ...

2020-09-02 · 1 min · 136 words

Tiny Core Linux 安装配置

简介 Tiny Core Linux是一个mini Linux操作系统,基于 BusyBox和FLTK提供基本功能。 其发行版本在11M-16M 官网上也提供Plus版本也只有106M。它很精致。 安装 操作系统安装 镜像下载 下载页面 http://tinycorelinux.net/downloads.html 我下载了两个版本镜像: x86版本: TinyCore-11.1.iso x86_64位版本:TinyCorePure64-11.1.iso 环境准备 我们使用的vmware 首先新建一个linux虚拟机, 我选的版本是其他Linux5.x或更高版本内核64位, 并添加了两块SATA的硬盘(默认的SCSI硬盘识别似乎有些问题) 开始安装 安装过程主要下面三个步骤 : 光盘启动操作系统; 配置网络 下载安装脚本安装; 1 . 选择镜像: 光盘镜像选择 x86版本:TinyCore-11.1.iso (不影响安装) 2 . 启动系统: 启动后会出现四个选项, 选择第三项 Boot TinyCore Boot TinyCore (on slow devices, waitusb=5) Boot Core (command line only) Boot Core (command line only on slow devices, waitusb=5) 可以看到系统后进入命令行窗口,但是这种模式下进行操作重启将全部丢失。要保留我们相关配置,需要挂载硬盘。 3 . 配置网络: 配置网卡地址路由及域名服务器。 sudo ifconfig eth0 192.168.xxx.202 netmask 255.255.255.0 sudo route add default gw 192.168.xxx.1 dev eth0 sudo echo nameserver 192.168.xxx.1 >> /etc/resolv.conf 4 . 下载安装脚本: 会联机下载相关安装包 ...

2020-09-01 · 4 min · 738 words

dhclient error while loading shared libraries libdns-export.so.1102

环境: cenos7(X86_64) 问题: 网站显示无法链接数据库,重启后发现无法链接服务器,通过管理端登录服务器 /var/log/messages显示 dhclient: error while loading shared libraries: libdns-export.so.1102: cannot open shared object file: No such file or directory 修复: 需要root权限 # ldconfig # dhclient --help # systemctl restart NetworkManager.service # ip -a 其他 查找过程及问题: 由于前一阵刚好在服务器上增加了防火墙相关配置,所以当时开始一直判断是防火墙设置问题。关闭防火墙后仍无法访问。 排除防火墙问题后,查看了下网络配置发现eth0没有相关IP信息。 在到/var/log/messages中查看错误信息,最终通过error定位到dhclient错误. 当然还是决定改为静态方式配置IP, 我用的是eth0, 修改下面配置即可 /etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE="eth0" BOOTPROTO="static" ONBOOT="yes" IPADDR=XXX.XXX.XXX.XXX NETMASK=255.255.255.0 GATEWAY=XXX.XXX.XXX.XXX DNS1=XXX.XXX.XXX.XXX 相关Bug Bug 1726534 与我遇到的问题一样, 大致的意思说就是说安装一些库的时候, 比如libapr虽然安装失败,导致 /etc/ld.so.cache 保存的是老版本libdns-export.so.100 不是新版本的libdns-export.so.1102 导致dhclient载入libdns-export.so.1102失败, 通过ldconfig重新更新一下 /etc/ld.so.cache即可。 serverfault.com-Cannot Access My Google VM after reboot

2020-08-25 · 1 min · 71 words

python excel文件中指定字段是否相等

工作需要检查相关excel数据信息, 查询一个表格中的指定位置编号,检查相关多个个相关表格中指定位置编号是否相同。 环境 windows10 python3.7 + openpyxl + xlrd 测试数据 目录结构 C:. │ checklist.py │ reference.xlsx │ └─newdir ├─dir1 │ data1.xls │ └─dir2 data2.xls 文件内容 参考表格 reference.xlsx A CODE-12345 表格1 data1.xls A CODE-12345 表格2 data2.xlsx A CODE-67890 代码 from openpyxl import load_workbook from openpyxl import Workbook import os import xlrd ## 获取待检查清单列表 def get_file(root_path,all_files=[]): files = os.listdir(root_path) for file in files: if not os.path.isdir(root_path + '/' + file): # 检查文件名包含"功能点", 以 "xls", "xlsx"为后缀的文件 if (file.endswith('.xls') or file.endswith('.xlsx')) \ and 'XXXX' in file: all_files.append(root_path + '/' + file) else: # 如果是目录,目录后增加'/'递归查找符合条件的文件 get_file((root_path+'/'+file),all_files) return all_files ## 获取参考文件指定位置编号 def get_request_no(root_path): files = os.listdir(root_path) for file in files: if not os.path.isdir(root_path + '/' + file): if file.endswith('.xls') or file.endswith('.xlsx') \ and 'YYYY' in file: print (file) ## only xlsx wb_in = load_workbook(file) ws_in = wb_in.active ## 查找第2行,第5列的编号 request_no = ws_in.cell(row=2, column=5) print (request_no.value + '\n') ##break return request_no.value; ## 遍历参考列表文件记录与参考文件表中需求编号不同的文件名 def check_file(files, request_no): result="" for file in files: ## 由于openpyxl, 不支持xls,这里使用的是xlrd库 wb_in = xlrd.open_workbook(file) ws_in = wb_in.sheets()[0] ## 编号是从0开始计数, 第8行, 第2列中的数据 file_request_no = ws_in.cell(rowx=7, colx=1) if str(file_request_no.value) != str(request_no): s = file_request_no.value + file +'\n' result += s return result def write_log(result): file=open("result.txt", "w") file.write(result) file.close() path = r'.\\ZZZZ' list=get_file(path) path = r'.' no=get_request_no(path) result=check_file(list, no) write_log(result) 运行结果 > python check.py > type result.txt CODE-67890.\\newdir/dir2/data2.xls 参考 Openpyxl Doc xlrd- API Reference

2020-08-24 · 2 min · 217 words

LeetCode – Count Univalue Subtrees

题目: Given a binary tree, count the number of uni-value subtrees. A Uni-value subtree means all nodes of the subtree have the same value. Example : Input: root = [5,1,5,5,5,null,5] 5 / \ 1 5 / \ \ 5 5 5 Output: 4 实现: 创建判断相同值子树方法isUnivalSubtrees, 判断其左、右节点与父节点是否相同,判定为Uni-value subtree(比较子节点与父节点val值时要先判断下对应left, right是否为空), 分别判断左子树和右子树的是否为Uni-value subtree, 如果是计数器累加。 isUnivalSubtrees 时间 复杂度O(n) 嵌入 countUnivalSubtrees后 O(n^2) /** * Definition of TreeNode: * class TreeNode { * public: * int val; * TreeNode *left, *right; * TreeNode(int val) { * this->val = val; * this->left = this->right = NULL; * } * } */ class Solution { public: /** * @param root: the given tree * @return: the number of uni-value subtrees. */ int countUnivalSubtrees(TreeNode * root) { int total = 0; if (root == nullptr){ return 0; } total = countUnivalSubtrees(root->left) + countUnivalSubtrees(root->right); if (isUnivalSubtrees(root)){ total +=1; } return total; } private: bool isUnivalSubtrees(TreeNode * root){ if (root == nullptr) { return true; } if (root->left!=nullptr && root->left->val != root->val) { return false; } if (root->right!=nullptr && root->right->val != root->val){ return false; } if (isUnivalSubtrees(root->left) && isUnivalSubtrees(root->right)){ return true; } return false; } }; 实现: 判断是否为Uni-value subtree的同时累计符合条件的子树数量,一起返回。 O(N) /** * Definition of TreeNode: * class TreeNode { * public: * int val; * TreeNode *left, *right; * TreeNode(int val) { * this->val = val; * this->left = this->right = NULL; * } * } */ class Solution { public: /** * @param root: the given tree * @return: the number of uni-value subtrees. */ int countUnivalSubtrees(TreeNode * root) { bool isUnival = true; return helperCount(root, isUnival); } int helperCount(TreeNode *root, bool& isUnival) { if (root == nullptr) { isUnival = true; return 0; } bool isLeftunival = true; bool isRightunival = true; int leftCount = 0; int rightCount = 0; leftCount = helperCount(root->left, isLeftunival); rightCount = helperCount(root->right, isRightunival); if (!isLeftunival || !isRightunival){ isUnival = false; } if (root->left !=nullptr && root->left->val != root->val ){ isUnival = false; } if (root->right !=nullptr && root->right->val != root->val ){ isUnival = false; } if (isUnival){ return leftCount+rightCount+1; } else { return leftCount+rightCount; } } }; 实现: 使用C++ pair ,判断Uni-value subtree和累计值放到一起返回。 /** * Definition of TreeNode: * class TreeNode { * public: * int val; * TreeNode *left, *right; * TreeNode(int val) { * this->val = val; * this->left = this->right = NULL; * } * } */ class Solution { public: /** * @param root: the given tree * @return: the number of uni-value subtrees. */ int countUnivalSubtrees(TreeNode * root) { pair<int, bool> re = helperCount(root); return re.first; } pair<int,bool> helperCount(TreeNode *root) { pair<int, bool> res = {0, true}; if (root == nullptr) { return res; } pair<int, bool> left, right; left = helperCount(root->left); right = helperCount(root->right); if (!left.second || !right.second){ res.second = false; } if (root->left !=nullptr && root->left->val != root->val ){ res.second = false; } if (root->right !=nullptr && root->right->val != root->val ){ res.second = false; } if (res.second){ res = {left.first+right.first+1, true}; } else { res = {left.first+right.first, false}; } return res; } }; 参考及引用: https://www.youtube.com/watch?v=7HgsS8bRvjo

2020-08-19 · 3 min · 497 words