数据库:Hive转Presto(五)

news2024/11/26 5:34:16

此篇将所有代码都补充完了,之前发现有的代码写错了,以这篇为准,以下为完整代码,如果发现我有什么考虑不周的地方,可以评论提建议,感谢。代码是想哪写哪,可能比较繁琐,还需要优化。

import re
import os
import tkinter.filedialog
from tkinter import *


class Hive2Presto:
    def __int__(self):
        self.t_funcs = ['substr', 'nvl', 'substring', 'unix_timestamp'] + \
                       ['to_date', 'concat', 'sum', 'avg', 'abs', 'year', 'month', 'ceiling', 'floor']
        self.time_funcs = ['date_add', 'datediff', 'add_months', 'date_sub']
        self.funcs = self.t_funcs + self.time_funcs
        self.current_path = os.path.abspath(__file__)
        self.dir = os.path.dirname(self.current_path)
        self.result = []
        self.error = []
        self.filename = ''

    def main(self):
        self.root = Tk()
        self.root.config(bg='#ff741d')  # 背景颜色设置为公司主题色^_^
        self.root.title('Hive转Presto')
        self.win_width = 550
        self.win_height = 500
        self.screen_width = self.root.winfo_screenwidth()
        self.screen_height = self.root.winfo_screenheight()
        self.x = (self.screen_width - self.win_width) // 2
        self.y = (self.screen_height - self.win_height) // 2
        self.root.geometry(f'{self.win_width}x{self.win_height}+{self.x}+{self.y}')

        font = ('楷体', 11)

        self.button = Button(self.root, text='转换', command=self.trans, bg='#ffcc8c', font=font, anchor='e')
        self.button.grid(row=0, column=0, padx=100, pady=10, sticky=W)

        self.file_button = Button(self.root, text='选择文件', command=self.choose_file, bg='#ffcc8c', font=font,
                                  anchor='e')
        self.file_button.grid(row=0, column=1, padx=0, pady=10, sticky=W)

        self.entry = Entry(self.root, width=65, font=font)
        self.entry.insert(0, '输入Hive代码')
        self.entry.grid(row=1, column=0, padx=10, pady=10, columnspan=2)
        self.entry.bind('<Button-1>', self.delete_text)

        self.text = Text(self.root, width=75, height=20)
        self.text.grid(row=2, column=0, padx=10, pady=10, columnspan=2)

        self.des_label = Label(self.root, text='可以复制结果,也有生成的文件,与选取的文件同文件夹', bg='#ffcc8c',
                               font=('楷体', 10))
        self.des_label.grid(row=3, column=0, padx=10, pady=10, columnspan=2)

        s = ''
        for i in range(0, (n := len(self.funcs)), 4):
            if i + 4 <= n:
                s += ','.join(self.funcs[i:i + 4]) + '\n'
            else:
                s += ','.join(self.funcs[i:]) + '\n'
        s = s[:-1]
        self.des_label1 = Label(self.root, text=s, bg='#ffcc8c',
                                font=('楷体', 10))
        self.des_label1.grid(row=4, column=0, padx=10, pady=10, columnspan=2)

        self.root.columnconfigure(0, minsize=10)
        self.root.columnconfigure(1, minsize=10)
        self.root.columnconfigure(0, pad=5)

        self.root.mainloop()

    def replace_func(self, s, res):
        """
        把搜索到函数整体取出来,处理括号中的参数
        :param s:
        :param res:
        :return:
        """
        for f in res:
            f1 = f.replace('\n', '').strip()
            f1 = re.sub(r'(\(s*)', '(', f1)
            # 搜索括号里的字符串
            if re.findall(r'(\w+)\(', f1):
                func_name = re.findall(r'(\w+)\(', f1)[0].strip()
            else:
                continue
            try:
                if 'date_add' == func_name.lower():
                    date, date_num = self.extact_func(f1, func_name)
                    s_n = f"date_add('day',{date_num},cast(substr(cast{date} as varchar,1,10) as date))"
                    s = s.replace(f, s_n)
                elif 'datediff' == func_name.lower():
                    date1, date2 = self.extact_func(f1, func_name)
                    s_n = f"date_add('day',{date2},cast(substr(cast{date1} as varchar,1,10) as date),cast(substr(cast{date1} as varchar),1,10) as date))"
                    s = s.replace(f, s_n)
                elif 'nvl' == func_name.lower():
                    s1, s2 = self.extact_func(f1, func_name)
                    s_n = f"coalesce({s1},{s2})"
                    s = s.replace(f, s_n)
                elif 'substr' == func_name.lower():
                    date, start, end = self.extact_func(f1, func_name)
                    s_n = f"substr(cast({date} as varchar),{start},{end}"
                    s = s.replace(f, s_n)
                elif 'substring' == func_name.lower():
                    date, start, end = self.extact_func(f1, func_name)
                    s_n = f"substring(cast({date} as varchar),{start},{end}"
                    s = s.replace(f, s_n)
                elif 'unit_timestamp' == func_name.lower():
                    date = self.extact_func(f1, func_name)[0]
                    s_n = f"to_unixtime(cast({date} as timestanp))"
                    s = s.replace(f, s_n)
                elif 'to_date' == func_name.lower():
                    date = self.extact_func(f1, func_name)[0]
                    s_n = f"cast({date} as date)"
                    s = s.replace(f, s_n)
                elif 'concat' == func_name.lower():
                    res = self.extact_func(f1, func_name)[0]
                    s_n = f'concat('
                    for r in res:
                        r = r.strip().replace('\n', '')
                        s_n += f"cast({r} as varchar),"
                    s_n = s_n[:-1] + ')'
                    s = s.replace(f, s_n)
                elif 'sum' == func_name.lower():
                    if 'unix_timestamp' in f1 or 'to_unixtime' in f1:
                        continue
                    ss = self.extact_func(f1, func_name)[0]
                    if 'if(' in ss.replace(' ', ''):
                        continue
                    s = self.func_trans(f, f1, func_name, ss, s)
                elif 'avg' == func_name.lower():
                    if 'unix_timestamp' in f1 or 'to_unixtime' in f1:
                        continue
                    ss = self.extact_func(f1, func_name)[0]
                    if 'if(' in ss.replace(' ', ''):
                        continue
                    s = self.func_trans(f, f1, func_name, ss, s)
                elif 'abs' == func_name.lower():
                    if 'unix_timestamp' in f1 or 'to_unixtime' in f1:
                        continue
                    ss = self.extact_func(f1, func_name)[0]
                    if 'if(' in ss.replace(' ', ''):
                        continue
                    s = self.func_trans(f, f1, func_name, ss, s)
                elif 'ceiling' == func_name.lower():
                    if 'unix_timestamp' in f1 or 'to_unixtime' in f1:
                        continue
                    ss = self.extact_func(f1, func_name)[0]
                    if 'if(' in ss.replace(' ', ''):
                        continue
                    s = self.func_trans(f, f1, func_name, ss, s)
                elif 'floor' == func_name.lower():
                    if 'unix_timestamp' in f1 or 'to_unixtime' in f1:
                        continue
                    ss = self.extact_func(f1, func_name)[0]
                    if 'if(' in ss.replace(' ', ''):
                        continue
                    s = self.func_trans(f, f1, func_name, ss, s)
                elif 'year' == func_name.lower():
                    date = self.extact_func(f1, func_name)[0]
                    s_n = f"year(cast(substr(cast({date} as varchar,1,10) as date))"
                    s = s.replace(f, s_n)
                elif 'month' == func_name.lower():
                    date = self.extact_func(f1, func_name)[0]
                    s_n = f"month(cast(substr(cast({date} as varchar,1,10) as date))"
                    s = s.replace(f, s_n)
                elif 'date_sub' == func_name.lower():
                    date, date_num = self.extact_func(f1, func_name)
                    s_n = f"date_add('day',-{date_num},cast(substr(cast{date} as varchar,1,10) as date))"
                    s = s.replace(f, s_n)
            except:
                self.error.append(f"源代码中{func_name}函数参数输入可能有错误,具体为:{f1}")
                continue
        if self.error:
            self.entry.delete(0, END)
            self.text.delete("1.0", END)
            self.text.insert("end", f"{s}")
            self.error.insert(0, '转换失败,有部分没有转成功\n')

            root_ex = Tk()
            root_ex.title('错误')
            win_width = 600
            win_height = 200
            screen_width = root_ex.winfo_screenwidth()
            screen_height = root_ex.winfo_screenheight()
            x = (screen_width - win_width) // 2
            y = (screen_height - win_height) // 2
            root_ex.geometry(f'{win_width}x{win_height}+{x}+{y}')
            label_ex = Label(root_ex, text="\n".join(self.error), font=("楷体", 10))
            label_ex.pack()
            root_ex.mainloop()

        return s

    def func_trans(self, f, f1, func_name, ss, s):
        if not ('+' in ss or '-' in ss or '*' in ss or '/' in ss):
            date = self.extact_func(f1, func_name)[0]
            s_n = f'{func_name}(cast{date} as double))'
            s = s.replace(f, s_n)
        else:
            res1 = self.mysplit(f1)
            s_n = f
            n = len(s_n)
            for item in res1:
                if any(c.isalpha() for c in item.replace(' ', '')):
                    idxs = s_n.find(item)
                    idxs = [idxs] if type(idxs) != list else idxs
                    for idx in idxs:
                        if idx + len(item) + 3 <= n:
                            if not 'as' in s_n[idx:idx + len(item) + 4]:
                                s_n = re.sub(rf'\b{item}\b', f'cast({item} as double)', s_n)
                        else:
                            s_n = re.sub(rf'\b{item}\b', f'cast({item} as double)', s_n)
                    s = s.replace(f, s_n)
        return s

    def choose_file(self):
        """
        如果代码太多,从text中输入会很卡,直接选择代码文件输入会很快
        :return:
        """
        self.filename = tkinter.filedialog.askopenfilename()
        if '/' in self.filename:
            self.filename = self.filename.replace('/', '\\')
        self.entry.delete(0, END)
        self.entry.insert(0, self.filename)

    def findvar(self, ss):
        """
        搜索与计算有关的字段
        :param ss:
        :return:
        """
        global r1
        b = ['+', '-', '*', '/', '=', '!=', '>', '<', '<=', '>=', '<>']
        result1 = []
        result2 = []
        result1_n = []
        result2_n = []
        res_ops = []
        res1_ops = []
        res_adj = []
        res1_adj = []
        for op in b:
            s_temp1 = ss.replace('\n', ' ')
            s_temp2 = ss.replace('\n', ' ')
            s_temp3 = ss.replace('\n', ' ')
            if op == '/' or op == '=':
                op = op
            elif op == '+' or op == '-' or op == '*' or op == '>' or op == '<':
                op = f'\\{op[0]}'
            else:
                op = f'\\{op[0]}\\{op[1]}'
            parttern = f'\s*-*\d+\s*{op}\s*\w+|' + f'\s*-*\d+\.\s*{op}\s*\w+\.\s*\w+|' \
                       + f'\s*\w+\.\s*\w+\s*{op}\s*\w+\.\s*\w+|' + f'\s*\w+\s*{op}\s*\w+\.\s*\w+|' \
                       + f'\s*\w+\.\s*\w+\s*{op}\s*\w+|' + f'\s*\w+\s*{op}\s*\w+'
            parttern1 = f'\s*\)+\s*{op}\s*\w+|' + f'\s*\)+\s*{op}\s*\w+\.\s*\w+|' \
                        + f'\s*\w+\s*{op}\s*\(+|' + f'f\s*\w+\.\s*{op}\s*\(+'
            parttern2 = f'\s*\w+\s*{op}\s*\w+|' + f'\s*\w+\s*{op}\s*\w+\.\s*\w+|' \
                        + f'\s*\w+\s*{op}\s*\w+|' + f'f\s*\w+\.\s*{op}\s*\w+'
            while True:
                res = re.findall(parttern, s_temp1)
                if not res:
                    break
                result2.extend(res)
                for r in res:
                    r1 = r.replace(' ', '').split(f'op')
                    result1.append(r1)
                    res_ops.append(f'{op}')
                    res_adj.append(False)
                s_temp1 = s_temp1.replace(f'{r1[0]}', '')

            # 搜索带括号的计算
            if op == '+' or op == '-' or op == '*' or op == '/':
                while True:
                    res = re.findall(parttern1, s_temp2)
                    if not res:
                        break
                    result2.extend(res)
                    for r in res:
                        r1 = r.replace(' ', '').split(f'{op}')
                        result1.append(r1)
                        res_ops.append(f'{op}')
                        res_adj.append(False)
                    tem = r1[0] if r1[0].strip() not in ['(', ')'] else r1[1]
                    s_temp2 = s_temp2.replace(f'{tem}', '')
            else:
                res = re.findall(parttern2, s_temp3)
                result2.extend(res)
                for r in res:
                    r1 = r.replace(' ', '').split(f'{op}')
                    result1.append(r1)
                    res_ops.append(f'{op}')
                    res_adj.append(True)

            str_ = re.findall(r'\'([^\']*)\'', ss)
            str_ = list(set(str_))
            str_ = [v.rstrip(' \n') for v in str_]
            for i, fun in enumerate(result1):
                flag = 0
                for item in fun:
                    if any(item.strip() in v for v in str_) or any(item.strip() == v for v in self.t_funcs):
                        break
                    flag += 1
                    if flag == 2 and result1[i] not in result1_n:
                        result1_n.append(result1[i])
                        result2_n.append(result2[i])
                        res1_ops.append(res_ops[i])
                        adj = result1[i][0] in self.time_funcs or result1[i][0] in self.time_funcs
                        res1_adj.append(adj)
            if result1_n:
                z = zip(result1_n, result2_n, res1_ops, res1_adj)
                z1 = sorted(z, key=lambda x: len(x[1].replace(' ', '')), reverse=True)
                result1_n, result2_n, res1_ops, res1_adj = zip(*z1)
            return result1_n, result2_n, res1_ops, res1_adj

    def mysplit(self, s):
        """
        分割字段
        :param s:
        :return:
        """
        s = s.strip().replace(')', '').replace('(', '')
        b = ['+', '-', '*', '/']
        res = [s]
        result = []
        for op in b:
            n_res = []
            for item in res:
                n_res.extend(item.split(op))
            res = n_res
        for item in res:
            if ' as ' not in item:
                result.append(re.findall(r'^[\w+_*]+$', item.replace(' ', ''))[0])
        result = list(set(res))
        return result

    def extact_func(self, s, func_name):
        res = []
        s = s[:-1].replace(f'{func_name}(', '', 1)
        com_idx = [i for i, v in enumerate(s) if v == ',']
        jd_com_idx = []
        for i in com_idx:
            s1 = s[0:i]
            if s1.count('(') == s1.count(')'):
                jd_com_idx.append(i)
        jd_com_idx.append(len(s))
        jd_com_idx.insert(0, -1)
        for i in range(1, len(jd_com_idx)):
            res.append(s[jd_com_idx[i - 1] + 1:jd_com_idx[i]])
        return res

    def sort_funcs(self, li):
        li = sorted(li, key=lambda x: x.count('('), reverse=True)
        li_n = []
        for l in li:
            li_n.append(l)
        return li_n

    def delete_text(self, event):
        self.entry.delete(0, END)
        self.filename = ''

    def trans(self):
        if self.filename:
            data = open(self.filename, 'r', encoding='utf-8').readlines()
            self.folder_path = os.path.dirname(self.filename)
            file_res = self.folder_path + r'\hive转presto_res.sql'
            os.startfile(f'{self.folder_path}')
        else:
            data = self.entry.get().split('\n')
            file_res = self.dir + r'\hive转presto_res.sql'
        data_n = []
        for s in data:
            if not s.rstrip(' \n'):
                continue
            if '”' in s:
                s = s.replace('“', '')
            if ',' in s:
                s = s.replace(',', ',')
            if '(' in s:
                s = s.replace('(', '(')
            if ')' in s:
                s = s.replace(')', ')')
            if (idx := s.find('--')) == -1:
                data_n.append(s + '\n')
            else:
                data_n.append(s[:idx] + '\n')

        data = ''.join(data_n)
        res1, res2, ops, adj = self.findvar(data)
        for i, ss in enumerate(res1):
            s_n = res2[i]
            s_n1 = res2[i]
            s_n2 = res2[i]
            s_t = res2[i]
            flag = 0
            for elem in ss:
                elem1 = elem.replace(' ', '')
                if any(c.isalpha() for c in elem1):
                    if ops[i] in ['=', '!=', '>', '<', '<=', '>=', '<>']:
                        if adj[i]:
                            if elem1 not in self.time_funcs:
                                s_n = re.sub(rf'\b{elem}\b', f'cast(substr({elem1},1,10) as date', s_n)
                                continue
                            else:
                                continue
                        if any(op in s_t for op in ['+', '-', '*', '/']):
                            s_n = re.sub(rf'\b{elem}\b', f'cast({elem1} as double)', s_n)
                        else:
                            s_n = re.sub(rf'\b{elem}\b', f'cast({elem1} as varchar)', s_n)
                    else:
                        if elem.strip() not in ['(', ')']:
                            s_n = re.sub(rf'\b{elem}\b', f'cast({elem1} as double)', s_n)
                    flag += 1
            data = data.replace(res2[i].strip(), s_n)
            if flag == 2:
                if any(op in s_t for op in ['+', '-', '*', '/']):
                    s_n1 = re.sub(rf'\b{ss[0]}\b', f'cast({ss[0]} as double)', s_n)
                    s_n2 = re.sub(rf'\b{ss[1]}\b', f'cast({ss[1]} as double)', s_n)
                else:
                    s_n1 = re.sub(rf'\b{ss[0]}\b', f'cast({ss[0]} as varchar)', s_n)
                    s_n2 = re.sub(rf'\b{ss[1]}\b', f'cast({ss[1]} as varchar)', s_n)
                data = data.replace(s_n1, s_n)
                data = data.replace(s_n2, s_n)

        self.error = []
        self.result = []
        for func_name in self.funcs:
            r = [m.start() for m in re.finditer(func_name, data.lower())]
            for idx in r:
                n = 1
                while True:
                    s = data[idx:idx + n]
                    if (s.count(')') == s.count('(') and s.count(')') != 0) and idx + n > len(data):
                        break
                    n += 1
                if s not in self.result and s.rstrip(' \n')[len(func_name)] == '(':
                    self.result.append(s)
        self.result = self.sort_funcs(self.result)
        res = self.replace_func(data, self.result)

        res_new = []
        for r in res.split('\n'):
            if r.rstrip(' \n'):
                res_new.append(r)
        res_new = '\n'.join(res_new)
        self.text.delete("1.0", END)
        self.text.insert("end", f'{res_new}')
        with open(file_res, 'w', encoding='utf-8') as f:
            f.write(res_new)


if __name__ == '__main__':
    pro = Hive2Presto()
    pro.__int__()
    pro.main()

效果如下所示:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1090307.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Kafka SASL认证授权(五)ACL源码解析

Kafka SASL认证授权(五)ACL源码解析。 官网地址:https://kafka.apache.org/ 一、ACL检查流程解析 一起看一下kafka server的启动与监听流程: Kafka -> KafkaServer -> SocketServer、KafkaRequestHandler 其中KafkaServer做相关的初始化,包括SocketServer 与 han…

实体解析实施的复杂性

实体的艺术表现斯特凡伯克纳 一、说明 实体解析是确定数据集中的两条或多条记录是否引用同一现实世界实体&#xff08;通常是个人或公司&#xff09;的过程。乍一看&#xff0c;实体分辨率可能看起来像一个相对简单的任务&#xff1a;例如&#xff0c;给定一张人物的两张照片&a…

AOMEI PXE Boot Free

两台电脑网线直连&#xff0c;不用设置固定IP&#xff0c;该软件包含DHCP。 名称: 3H3AOMEIPXEBootFree.rar 大小: 13068734 字节 (12 MiB) SHA1: 1e606c8c1ee3badf8af9a87f61fdf2e332b773e6 名称: PXEBoot.exe 大小: 13124928 字节 (12 MiB) SHA1: 95286ac18e9b81c2a68412c40…

尿检设备“智能之眼”:维视智造推出MV-MC 系列医疗专用相机

​ 尿液分析是临床检验的基础常规项目&#xff0c;随着医疗设备的不断发展&#xff0c;尿液分析相关仪器的国产化和自动化程度也进一步提升。2022 年国内尿液分析市场的规模约为 28 亿元&#xff0c;激烈的竞争推动了尿检仪器自动化、智能化升级&#xff0c;在仪器中加入机器视…

布朗大学发现GPT-4存在新问题,可通过非常见语言绕过限制

&#x1f989; AI新闻 &#x1f680; 布朗大学发现GPT-4存在新漏洞&#xff0c;可通过非常见语言绕过限制 摘要&#xff1a;布朗大学计算机科学研究人员发现了OpenAI的GPT-4存在新漏洞&#xff0c;利用不太常见的语言如祖鲁语和盖尔语可以绕过各种限制。研究人员测试了GPT-4对…

如何做好数据分析中的数据可视化?

数据可视化在数据分析中扮演着重要的角色&#xff0c;它帮助我们更好地理解和传达数据的特征、趋势和规律。以下是关于如何做好数据分析中的数据可视化的详细介绍。 一、准备工作 1. 理解数据 在进行数据可视化之前&#xff0c;首先要对数据有一个清晰的理解。了解数据的来源…

【大数据】Hadoop MapReduce与Hadoop YARN(学习笔记)

一、Hadoop MapReduce介绍 1、设计构思 1&#xff09;如何对付大数据处理场景 对相互间不具有计算依赖关系的大数据计算任务&#xff0c;实现并行最自然的办法就是采取MapReduce分而治之的策略。 不可拆分的计算任务或相互间有依赖关系的数据无法进行并行计算&#xff01; …

LiveMedia视频中间件如何与第三方系统实现事件录像关联

一、平台简介 LiveMedia视频中间件是支持部署到本地服务器或者云服务器的纯软件服务&#xff0c;也提供服务器、GPU一体机全包服务&#xff0c;提供视频设备管理、无插件、跨平台的实时视频、历史回放、语音对讲、设备控制等基础功能&#xff0c;支持视频协议有海康、大华私有协…

Qt事件系统 day7

Qt事件系统 day7 事件系统 在Qt中&#xff0c;事件是派生自抽象QEvent类的对象&#xff0c;它表示应用程序内发生的事情或应用程序需要知道的外部活动的结果。事件可以由QObject子类的任何实例接收和处理&#xff0c;但它们与小部件尤其相关。Qt程序需要在main()函数创建一个…

【iOS】Mac M1安装iPhone及iPad的app时设置问题

【iOS】Mac M1安装iPhone及iPad的app时设置问题 简介一&#xff0c;设置问题二&#xff0c;适配问题 简介 由于 苹果M1芯片的Mac可用安装iPhone以及iPad应用&#xff0c;因为开发者并没有适配Mac&#xff0c;因此产生了很多奇怪问题&#xff0c;这里总结归纳Mac M1安装iPhone和…

C++之委托构造函数实例(二百四十三)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

学信息系统项目管理师第4版系列26_项目绩效域(下)

1. 项目工作绩效域 1.1. 涉及项目工作相关的活动和职能 1.2. 预期目标 1.2.1. 高效且有效的项目绩效 1.2.2. 适合项目和环境的项目过程 1.2.3. 干系人适当的沟通和参与 1.2.4. 对实物资源进行了有效管理 1.2.5. 对采购进行了有效管理 1.2.6. 有效处理了变更 1.2.7. 通…

第八章:网络设备文件管理)

网络设备文件管理 一、网络设备的文件系统1. 网络设备的存储方式2. 网络设备的操作 二、文件管理1. 配置文件的操作2. 配置文件的显示与维护![ ](https://img-blog.csdnimg.cn/a4f36f4e8f50422eb76be4ea7794bad9.png) 三、网络连通测试四、系统调试 一、网络设备的文件系统 1. …

2023年09月 C/C++(六级)真题解析#中国电子学会#全国青少年软件编程等级考试

C/C编程&#xff08;1~8级&#xff09;全部真题・点这里 Python编程&#xff08;1~6级&#xff09;全部真题・点这里 第1题&#xff1a;生日相同 在一个有180人的大班级中&#xff0c;存在两个人生日相同的概率非常大&#xff0c;现给出每个学生的名字&#xff0c;出生月日。试…

idea 启动出现 Failed to create JVM JVM Path

错误 idea 启动出现如下图情况 Error launching IDEA If you already a 64-bit JDK installed, define a JAVA_HOME variable in Computer > System Properties> System Settings > Environment Vanables. Failed to create JVM. JVM Path: D:\Program Files\JetB…

Redis微服务架构

Redis微服务架构 缓存设计 缓存穿透 缓存穿透是指查询一个根本不存在的数据&#xff0c;缓存层和存储层都不会命中&#xff0c;通常出于容错的考虑&#xff0c;如果从存储层查不到数据则不写入缓层。 缓存穿透将导致不存在的数据每次请求都要到存储层去查询&#xff0c;失去…

真正牛的项目经理,都做到了这几点

大家好&#xff0c;我是老原。 不管你是在大厂还是小厂&#xff0c;都可以看到这么一群人&#xff0c;他们具备&#xff1a;优秀的产品规划、持续的商务拓展、准时交付项目/产品。 然后大部分人是&#xff1a;一般的产品规划、眼睁睁看着客户流失、项目/产品交付不断推迟。 …

private key ssh连接服务器

这里用到的软件是PuTTY。 https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html 保存本地rsa文件后&#xff0c;打开软件PuTTYgen&#xff0c;点击Load导入文件&#xff0c;输入Key passphrase即密码&#xff0c;保存至本地。 随后在PuTTY配置ssh的用户名 来Cred…

网络报修心得

文章目录 JNU 网络牛牛有线锐捷跳出不允许开启VPN 为他人代理 JNU 网络牛牛 有线 锐捷跳出不允许开启VPN 为他人代理 问题表现&#xff1a;打游戏开启加速器后&#xff0c;频繁冒出提示&#xff0c;然后频繁下线&#xff0c;但是电脑无线使用正常问题原因&#xff1a;一般是加…

Apache Doris 在小鹅通的应用实践

峰会官网已上线&#xff0c;最新议程请关注&#xff1a;doris-summit.org.cn 点击报名 先到先得 本文导读&#xff1a; 随着网络直播规模的不断扩大&#xff0c;在线知识服务在直播行业中迎来了广阔的发展机遇。小鹅通作为一家以用户服务为核心的技术服务商&#xff0c;通过多平…