Java面试题训练助手 Python版

需要安装环境

pip install openai

python 复制代码
"""
🚀 Java面试题训练助手 Python版 v2.3 (命令优化版)
日期: 2025年8月22日 星期五 15:00
优化重点: 命令指南改为数字编号 + 快捷操作
"""
import os 
import json
import time 
import socket
import threading 
import urllib.request  
import urllib.error   
from collections import deque
from datetime import datetime 
import hashlib
import pickle 
import platform 
from openai import OpenAI as DeepSeekClient 
from openai import APIConnectionError, RateLimitError, APIStatusError 
 
# 配置参数 
API_KEY = "sk-55133f0b231547108==="  # 替换为您的真实API密钥
MODEL = "deepseek-chat"
MAX_RETRY = 4
CACHE_EXPIRE_MIN = 180
HISTORY_SIZE = 20
CACHE_FILE = "interview_cache.pkl"  
HISTORY_FILE = "history_data.json"  
RECORD_FILE = "interview_records.txt"  # 记录文件
SYSTEM_NAME = platform.system()  
 
# 专业提示词模板 
SYSTEM_PROMPT = (
    "你是资深Java技术专家(阿里P8级别),请回答面试题,答案控制在500字以内\n"
)
 
# 初始化DeepSeek客户端
deepseek_client = DeepSeekClient(
    api_key=API_KEY,
    base_url="https://api.deepseek.com"
)
 
class CacheEntry:
    """增强型缓存条目"""
    def __init__(self, answer):
        self.answer  = answer 
        self.timestamp  = time.time()  
        self.access_count  = 1 
    
    def is_expired(self):
        return (time.time()  - self.timestamp)  > CACHE_EXPIRE_MIN * 60 
    
    def update_access(self):
        self.access_count  += 1 
        self.timestamp  = time.time()  
 
def get_current_datetime():
    """优化时间格式显示"""
    now = datetime.now()  
    return now.strftime(f"%Y年%m月%d日 %H:%M:%S")
 
def format_answer(answer):
    return answer 
 
def get_question_hash(question):
    """生成问题哈希值作为缓存键"""
    return hashlib.md5(question.encode('utf-8')).hexdigest()  
 
def load_cache():
    """加载持久化缓存"""
    if not os.path.exists(CACHE_FILE):  
        return {}
    
    try:
        with open(CACHE_FILE, 'rb') as f:
            return pickle.load(f)  
    except:
        return {}
 
def save_cache(cache):
    """保存缓存到文件"""
    with open(CACHE_FILE, 'wb') as f:
        pickle.dump(cache, f)
 
def load_history():
    """加载历史记录"""
    if not os.path.exists(HISTORY_FILE):  
        return deque(maxlen=HISTORY_SIZE)
    
    try:
        with open(HISTORY_FILE, 'r', encoding='utf-8') as f:
            data = json.load(f)  
            return deque(data, maxlen=HISTORY_SIZE)
    except:
        return deque(maxlen=HISTORY_SIZE)
 
def save_history(history):
    """保存历史记录"""
    with open(HISTORY_FILE, 'w', encoding='utf-8') as f:
        json.dump(list(history), f, ensure_ascii=False, indent=2)
 
def record_to_file(question, answer, timestamp):
    """将问题和答案记录到本地txt文件"""
    try:
        with open(RECORD_FILE, 'a', encoding='utf-8') as f:
            # 写入分隔线
            f.write("=" * 80 + "\n")
            # 写入时间
            f.write(f"记录时间: {timestamp}\n\n")
            # 写入问题
            f.write(f"问题: {question}\n\n")
            # 写入答案
            f.write(f"答案:\n{answer}\n\n")
        print(f"📝 已自动记录到 {os.path.abspath(RECORD_FILE)}")
    except Exception as e:
        print(f"⚠️ 记录失败: {str(e)}")
 
def check_internet():
    """检查网络连接"""
    try:
        urllib.request.urlopen('https://www.baidu.com',  timeout=5)
        return True 
    except:
        return False
 
def get_ai_answer(question):
    """使用DeepSeek官方SDK调用API"""
    retry_delay = 1.5 
    for attempt in range(MAX_RETRY):
        try:
            response = deepseek_client.chat.completions.create( 
                model=MODEL,
                messages=[
                    {"role": "system", "content": SYSTEM_PROMPT},
                    {"role": "user", "content": question}
                ],
                stream=False
            ) 
            return response.choices[0].message.content.strip() 
                
        except RateLimitError:
            wait_time = retry_delay * (attempt + 1)
            print(f"⏳ 请求被限流,{wait_time:.1f}秒后重试...")
            time.sleep(wait_time) 
            continue
            
        except (APIConnectionError, TimeoutError) as e:
            if attempt < MAX_RETRY - 1:
                wait_time = retry_delay * (2 **attempt)
                print(f"⚠️ 网络错误({str(e)}), {wait_time:.1f}秒后重试...")
                time.sleep(wait_time) 
                continue 
            raise ConnectionError(f"网络错误: {str(e)}") from e
            
        except APIStatusError as e:
            if e.status_code  == 429:
                wait_time = retry_delay * (attempt + 2)
                print(f"⏳ 服务器限流,{wait_time:.1f}秒后重试...")
                time.sleep(wait_time) 
                continue 
            raise Exception(f"API错误: HTTP {e.status_code}  - {e.message}") 
            
        except Exception as e:
            if attempt < MAX_RETRY - 1:
                wait_time = retry_delay * (attempt + 1)
                print(f"⚠️ 发生错误({str(e)}), {wait_time:.1f}秒后重试...")
                time.sleep(wait_time) 
                continue 
            raise Exception(f"请求失败: {str(e)}") 
            
    raise Exception("API请求失败,超过最大重试次数")
 
def show_history():
    """优化历史记录显示"""
    if not history:
        print("\n📜 历史记录为空")
        return 
    
    print("\n📜 历史记录(最近20条):")
    for i, record in enumerate(reversed(history), 1):
        print(f"{i}. [{record['time']}]")
        print(f"  问题: {record['question'][:80]}{'...' if len(record['question']) > 80 else ''}")
        
        if 'answer' in record:
            ans_preview = record['answer'].split('\n')[0][:100]
            print(f"  首句: {ans_preview}...")
        else:
            print("  状态: 未获取答案")
        print("-" * 60)
 
def display_welcome():
    """优化欢迎界面,使用数字命令指南"""
    os.system('cls'  if SYSTEM_NAME == 'Windows' else 'clear')
    print("=" * 80)
    print(f"🚀 Java面试题训练助手 Python版 v2.3 | {get_current_datetime()}")
    print("=" * 80)
    print("📋 命令指南 (输入数字执行对应操作):")
    print("  1 - 输入Java面试问题")
    print("  2 - 查看问答历史")
    print("  3 - 清空历史记录")
    print("  4 - 显示帮助信息")
    print("  5 - 结束程序")
    print("-" * 80)
    print("💡 提示: 所有问答将自动记录到 interview_records.txt 文件")
    print("=" * 80 + "\n")
 
def clear_history():
    """清空历史功能"""
    global history
    history = deque(maxlen=HISTORY_SIZE)
    save_history(history)
    print("\n🗑️ 历史记录已清空!")
 
def show_help():
    """优化帮助信息"""
    print("\n📘 使用帮助:")
    print("1. 输入数字1可以提问Java相关面试题 (如: 'HashMap实现原理')")
    print("2. 问题后加'深入'获取更详细分析 (如: 'JVM内存模型 深入')")
    print("3. 问题中包含'代码'将获得完整可运行示例")
    print("4. 系统自动缓存答案,相同问题无需重复请求")
    print("5. 所有问答内容会自动记录到interview_records.txt文件")
    print("6. 每日首次运行将加载历史记录")
    print("\n🔌 API状态: 使用DeepSeek官方SDK v1.0")
    print("   基础URL: https://api.deepseek.com/v1") 
    print("   超时设置: 20秒 (连接+响应)")
    print("\n💡 专业提示: 使用具体技术点提问效果更佳 (如代替'多线程'用'ThreadLocal原理')")
 
def loading_animation(stop_event):
    """优化的加载动画"""
    chars = ["🌑", "🌒", "🌓", "🌔", "🌕", "🌖", "🌗", "🌘"]
    i = 0
    while not stop_event.is_set():  
        print(f"\r⏳ 思考中 {chars[i % len(chars)]}", end="", flush=True)
        i += 1 
        time.sleep(0.15)  
 
def main():
    """主程序优化,支持数字命令操作"""
    global history, answer_cache 
    
    # 检查网络连接 
    if not check_internet():
        print("\n⚠️ 网络连接不可用,请检查网络后再运行程序!")
        return
    
    # 初始化数据 
    answer_cache = load_cache()
    history = load_history()
    
    # 显示欢迎界面 
    display_welcome()
    
    while True:
        try:
            # 提示用户输入命令或问题
            user_input = input("\n请输入操作编号(1-5)或直接输入问题: ").strip()
            
            if not user_input:
                continue 
                
            # 处理数字命令
            if user_input == "1":
                question = input("请输入Java面试题: ").strip()
                if not question:
                    print("⚠️ 问题不能为空,请重新输入")
                    continue
            elif user_input == "2":
                show_history()
                continue
            elif user_input == "3":
                clear_history()
                continue
            elif user_input == "4":
                show_help()
                continue
            elif user_input == "5":
                break
            else:
                # 非数字输入视为问题
                question = user_input
            
            # 记录历史
            current_time = get_current_datetime()
            record = {
                "time": current_time,
                "question": question 
            }
            history.append(record)  
            
            # 生成缓存键
            question_hash = get_question_hash(question)
            
            # 检查缓存
            cache_entry = answer_cache.get(question_hash)  
            if cache_entry and not cache_entry.is_expired():  
                cache_entry.update_access()  
                print("\n♻️ 缓存答案 (命中率提升):")
                print(format_answer(cache_entry.answer))  
                
                # 更新记录 
                record["answer"] = cache_entry.answer  
                # 自动记录到文件
                record_to_file(question, cache_entry.answer, current_time)
                continue
                
            # 获取新答案
            stop_event = threading.Event()
            loader = threading.Thread(target=loading_animation, args=(stop_event,))
            loader.daemon = True
            loader.start()  
            
            try:
                start_time = time.time()  
                answer = get_ai_answer(question)
				
                stop_event.set()  
                loader.join()  
                
                response_time = time.time()  - start_time 
                print(f"\r✅ 获取成功! (耗时: {response_time:.1f}s)" + " " * 20)
                # 缓存答案 
                answer_cache[question_hash] = CacheEntry(answer)
                record["answer"] = answer 
                
                print("\n🧠 专业参考答案:")
                formatted = format_answer(answer)
                print(formatted)
                
                # 自动记录到文件
                record_to_file(question, formatted, current_time)
                    
            except Exception as e:
                stop_event.set()  
                loader.join()  
                print(f"\r❌ 获取失败: {str(e)}")
                record["error"] = str(e)
                
        except KeyboardInterrupt:
            print("\n🛑 操作已取消")
            continue 
            
    # 退出前保存数据 
    save_cache(answer_cache)
    save_history(history)
    print(f"\n感谢使用! 本次会话共处理 {len(history)} 道面试题")
    print(f"所有记录已保存到 {os.path.abspath(RECORD_FILE)}")
    print("缓存和历史记录已自动保存,下次启动可继续使用")
 
if __name__ == "__main__":
    try:
        main()
    except Exception as e:
        print(f"⚠️ 程序异常: {str(e)}")
        print("建议: 检查网络连接或API密钥配置")