iOS:练习题中如何用技术去实现一个连线题
一、介绍
本人做的app涉及的是教育行业,所以关于练习题的开发肯定是家常便饭。例如,选择题、填空题、连线题、判断题等,每一种题型都需要技术去实现,没啥多大难度,这里呢,就给出实现连线题的核心代码吧。过了年后,好久没写笔记了,今天就简单开始吧~~~
二、思想
采用上下文在画图的方法,首先确定起点和终点的坐标,然后通过两点画一条直线。
三、代码
(1)常量定义
lianXianHeader.h
//
// LianXianHeader.h
// LianxianDemo
//
// Created by 夏远全 on 2018/2/9.
// Copyright © 2018年 beijing. All rights reserved.
// #ifndef LianXianHeader_h
#define LianXianHeader_h static CGFloat const BWidth = ; //按钮的宽度
static CGFloat const BHeight = ; //按钮的高度
static CGFloat const margin = ; //按钮与屏幕的左边距、右边距
static CGFloat const Lpadding = ; //左边按钮上下间距
static CGFloat const Rpadding = ; //右边按钮上下间距 static NSString* const kBeginPositionNotification = @"kBeginPositionNotification";
static NSString* const kEndPositionNotification = @"kEndPositionNotification";
static NSString* const kClearAllLineNotification = @"kClearAllLineNotification";
static NSString* const kFreshDrawLineNotification = @"kFreshDrawLineNotification"; #endif /* LianXianHeader_h */
(2)连线模型
lianXianModel.h
//
// LianXianModel.h
// LianxianDemo
//
// Created by 夏远全 on 2018/2/8.
// Copyright © 2018年 beijing. All rights reserved.
// #import <Foundation/Foundation.h>
#import <UIKit/UIKit.h> @interface LianXianModel : NSObject
@property (nonatomic, strong) NSArray *questions;
@property (nonatomic, strong) NSArray *options;
@property (nonatomic, strong) NSArray *relationships;
@end
lianXianModel.m
//
// LianXianModel.m
// LianxianDemo
//
// Created by 夏远全 on 2018/2/8.
// Copyright © 2018年 beijing. All rights reserved.
// #import "LianXianModel.h" @implementation LianXianModel @end
(3)绘制连线
lianXianDrawView.h
//
// LianxianDrawView.h
// Ubbsz
//
// Created by 夏远全 on 2018/2/9.
// Copyright © 2018年 beijing. All rights reserved.
//
// #import <UIKit/UIKit.h> @interface LianxianDrawView : UIView @end
lianXianDrawView.m
//
// LianxianDrawView.m
// Ubbsz
//
// Created by 夏远全 on 2018/2/9.
// Copyright © 2018年 beijing. All rights reserved.
// #import "LianxianDrawView.h"
#import "LianXianHeader.h" @interface LianxianDrawView()
{
NSMutableArray *pointArray; //存储当前的一对坐标,起始点和终止点
NSMutableArray *lineArray; //存储全部的连线,每一条连线就是一对坐标
NSString *startPointString; //当前起点
NSString *endPointString; //当前起点
CGFloat lineWidth;
} @end @implementation LianxianDrawView //对进行重写,以便在视图初始化的时候创建并设置自定义的Context
- (id)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) { [self setupDefaultValue];
[self regesterNotification];
}
return self;
} //初始值
- (void)setupDefaultValue{ pointArray=[[NSMutableArray alloc]init];
lineArray=[[NSMutableArray alloc]init];
lineWidth = 2.0f;
self.backgroundColor = [UIColor colorWithRed:/255.0 green:/255.0 blue:/255.0 alpha:];
} //注册通知
- (void)regesterNotification{ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(toucheBegin:) name:kBeginPositionNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(toucheEnd:) name:kEndPositionNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(clearLine:) name:kClearAllLineNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(freshNeedsDisplay:) name:kFreshDrawLineNotification object:nil];
} //对drawRect进行重写
- (void)drawRect:(CGRect)rect
{ //获取当前上下文,
CGContextRef context=UIGraphicsGetCurrentContext();
CGContextBeginPath(context);
CGContextSetLineWidth(context, lineWidth);
//线条拐角样式,设置为平滑
CGContextSetLineJoin(context,kCGLineJoinRound);
//线条开始样式,设置为平滑
CGContextSetLineCap(context, kCGLineCapRound); //查看lineArray数组里是否有线条,有就将之前画的重绘,没有只画当前线条
if ([lineArray count] > ) { for (int i=; i < [lineArray count]; i++) {
NSArray * array=[NSArray arrayWithArray:[lineArray objectAtIndex:i]];
if ([array count] > && [array count]% == ) { CGContextBeginPath(context);
CGPoint myStartPoint = CGPointFromString(array.firstObject);
CGContextMoveToPoint(context, myStartPoint.x, myStartPoint.y); CGPoint myEndPoint = CGPointFromString(array.lastObject);
CGContextAddLineToPoint(context, myEndPoint.x,myEndPoint.y); CGContextSetStrokeColorWithColor(context,[[UIColor grayColor] CGColor]);
CGContextSetLineWidth(context, lineWidth);
CGContextStrokePath(context);
}
}
}
} //接收起点按钮点击通知事件
- (void)toucheBegin:(NSNotification *)notification{ CGRect beginFrame = [notification.object CGRectValue];
CGPoint startPoint = CGPointMake(CGRectGetMaxX(beginFrame), CGRectGetMidY(beginFrame));
startPointString = NSStringFromCGPoint(startPoint); if (pointArray.count==) {
[pointArray addObject:startPointString];
}
else{
[pointArray replaceObjectAtIndex: withObject:startPointString];
}
} //接收终点按钮点击通知事件
- (void)toucheEnd:(NSNotification *)notification{ CGRect endFrame = [notification.object CGRectValue];
CGPoint endPoint = CGPointMake(CGRectGetMinX(endFrame), CGRectGetMidY(endFrame));
endPointString = NSStringFromCGPoint(endPoint); if (pointArray.count==) {
[pointArray replaceObjectAtIndex: withObject:endPointString];
}
else{
[pointArray addObject:endPointString];
} [self clearSomeHistoryLineView];
[self addLA];
[self setNeedsDisplay];
} //接收清除按钮点击通知事件
- (void)clearLine:(NSNotification *)notification{
[self clearAllLineView];
} //接收重新绘制通知事件
- (void)freshNeedsDisplay:(NSNotification *)notification{ NSArray *relationslineArray = notification.object;
lineArray = [NSMutableArray arrayWithArray:relationslineArray];
[self setNeedsDisplay];
} //添加连线
-(void)addLA{
NSArray *array = [NSArray arrayWithArray:pointArray];
[lineArray addObject:array];
[pointArray removeAllObjects];
} //清除所有的连线
- (void)clearAllLineView
{
[pointArray removeAllObjects];
[lineArray removeAllObjects];
[self setNeedsDisplay];
} //移除历史交叉重复的连线
- (void)clearSomeHistoryLineView{ NSMutableArray *arrayM = [NSMutableArray array];
for (int i=; i < [lineArray count]; i++) {
NSArray *array = [NSArray arrayWithArray:[lineArray objectAtIndex:i]];
if ([array count] > ) { NSString *hisBePointString = array.firstObject;
NSString *hisEnPointString = array.lastObject; if ([startPointString isEqualToString:hisBePointString] || [endPointString isEqualToString:hisEnPointString]) {
[arrayM addObject:array];
}
}
}
[lineArray removeObjectsInArray:arrayM];
} //移除通知
-(void)dealloc{
[[NSNotificationCenter defaultCenter] removeObserver:self];
} @end
(4)计算尺寸
LianXianFrameUitity.h
//
// LianXianSizeUitity.h
// LianxianDemo
//
// Created by 夏远全 on 2018/2/9.
// Copyright © 2018年 beijing. All rights reserved.
// #import <Foundation/Foundation.h>
#import "LianXianModel.h" @interface LianXianFrameUitity : NSObject + (CGRect)calculateSizeWithModel:(LianXianModel *)lianxianModel; @end
LianXianFrameUitity.m
//
// LianXianSizeUitity.m
// LianxianDemo
//
// Created by 夏远全 on 2018/2/9.
// Copyright © 2018年 beijing. All rights reserved.
// #import "LianXianFrameUitity.h"
#import "LianXianHeader.h" @implementation LianXianFrameUitity + (CGRect)calculateSizeWithModel:(LianXianModel *)lianxianModel{ NSUInteger questionsCount = lianxianModel.questions.count;
NSUInteger optionsCount = lianxianModel.options.count; CGFloat LHeight = questionsCount * (BHeight+Lpadding) + Lpadding;
CGFloat RHeight = optionsCount * (BHeight+Rpadding) + Rpadding; CGFloat kWidth = [UIScreen mainScreen].bounds.size.width; //默认宽度为屏幕的宽 return CGRectMake(, , kWidth, MAX(LHeight, RHeight));
} @end
(5)创建组件
LianXianComponentsView.h
//
// LianXianComponentsView.h
// LianxianDemo
//
// Created by 夏远全 on 2018/2/6.
// Copyright © 2018年 beijing. All rights reserved.
// #import <UIKit/UIKit.h>
#import "LianXianModel.h" @interface LianXianComponentsView : UIView
@property (nonatomic, strong) LianXianModel *lianxianModel;
@end
LianXianComponentsView.m
//
// LianXianComponentsView.m
// LianxianDemo
//
// Created by 夏远全 on 2018/2/6.
// Copyright © 2018年 beijing. All rights reserved.
// #import "LianXianComponentsView.h"
#import "LianxianDrawView.h"
#import "LianXianHeader.h" @interface LianXianComponentsView() {
NSMutableArray *_leftBtns;
NSMutableArray *_rightBtns;
UIButton *currentLeftBtn;
CGFloat borderWith;
} @end @implementation LianXianComponentsView //对进行重写,以便在视图初始化的时候创建并设置自定义的Context
- (id)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
[self setupDefalutValue];
}
return self;
} //设置默认值
- (void)setupDefalutValue{ self.backgroundColor = [UIColor clearColor];
borderWith = 2.5;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(restStatus:) name:kClearAllLineNotification object:nil];
} //接收模型
-(void)setLianxianModel:(LianXianModel *)lianxianModel{ _lianxianModel = lianxianModel;
[self setupLianXianUnit]; if (lianxianModel && lianxianModel.relationships.count>) {
[self showLianXianResult];
}
else{
[self listClickLeftButton];
}
} //绘制连线选项
- (void)setupLianXianUnit{ _leftBtns = [[NSMutableArray array] init];
_rightBtns = [[NSMutableArray array] init]; CGFloat kWidth = self.frame.size.width;
CGFloat kHeight = self.frame.size.height;
CGFloat LY = (kHeight-(BHeight+Lpadding)*(self.lianxianModel.questions.count-) - BHeight)/;
CGFloat RY = (kHeight-(BHeight+Rpadding)*(self.lianxianModel.options.count-) - BHeight)/; for (NSInteger i =; i < self.lianxianModel.questions.count; i++) {
UIButton *btn = [self createButtonWithFrame:CGRectMake(margin, LY+(BHeight+Lpadding)*i, BWidth, BHeight) title:[NSString stringWithFormat:@"%@",self.lianxianModel.questions[i]] tag:i];
[self addSubview:btn];
[_leftBtns addObject:btn];
} for (NSInteger i =; i< self.lianxianModel.options.count; i++) {
UIButton *btn = [self createButtonWithFrame:CGRectMake(kWidth-margin-BWidth, RY+(BHeight+Rpadding)*i, BWidth, BHeight) title:[NSString stringWithFormat:@"%@",self.lianxianModel.options[i]] tag:i];
[self addSubview:btn];
[_rightBtns addObject:btn];
}
} -(UIButton *)createButtonWithFrame:(CGRect)frame title:(NSString *)title tag:(NSInteger)tag{ UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = frame;
btn.layer.cornerRadius = 5.0;
btn.layer.borderColor = [UIColor lightGrayColor].CGColor;
btn.layer.borderWidth = borderWith;
btn.layer.masksToBounds = YES;
btn.tag = tag; [btn setBackgroundImage:[self imageWithColor:[UIColor whiteColor]] forState:UIControlStateNormal];
[btn setBackgroundImage:[self imageWithColor:[UIColor colorWithRed:/255.0 green:/255.0 blue:/255.0 alpha:]] forState:UIControlStateHighlighted];
[btn setBackgroundImage:[self imageWithColor:[UIColor colorWithRed:/255.0 green:/255.0 blue:/255.0 alpha:]] forState:UIControlStateSelected]; [btn addTarget:self action:@selector(tapBtn:) forControlEvents:UIControlEventTouchUpInside];
[btn setTitle:title forState:UIControlStateNormal];
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; return btn;
} - (UIImage *)imageWithColor:(UIColor *)color
{
CGFloat imageW = ;
CGFloat imageH = ;
UIGraphicsBeginImageContextWithOptions(CGSizeMake(imageW, imageH), NO, 0.0);
[color set];
UIRectFill(CGRectMake(, , imageW, imageH));
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
} -(void)tapBtn:(UIButton *)btn{ //判断左边按钮是否处于选择状态,只有首先左边处于此状态下,右边的按钮点击才能进行连线操作(当前仅支持单向连线)
if ([_rightBtns containsObject:btn]) {
BOOL isLeftBtnSelected = NO;
for (UIButton *leftBtn in _leftBtns) {
if (leftBtn.selected) {
isLeftBtnSelected = YES;
break;
}
}
if (!isLeftBtnSelected) {
return;
}
} if ([_leftBtns containsObject:btn]) { //设置连线起点
currentLeftBtn.selected = NO;
currentLeftBtn.layer.borderColor = [UIColor lightGrayColor].CGColor;
btn.selected = YES;
currentLeftBtn = btn;
currentLeftBtn.layer.borderColor = [UIColor colorWithRed:/255.0 green:/255.0 blue:/255.0 alpha:].CGColor; //设置终点按钮可以选中状态
for (UIButton *rightBtn in _rightBtns) {
rightBtn.layer.borderColor = [UIColor colorWithRed:/255.0 green:/255.0 blue:/255.0 alpha:].CGColor;
} //发送起点通知
[[NSNotificationCenter defaultCenter] postNotificationName:kBeginPositionNotification object:[NSValue valueWithCGRect:btn.frame]];
} if ([_rightBtns containsObject:btn]) { for (UIButton *leftBtn in _leftBtns) {
if (leftBtn.selected) { //发送终点通知
[[NSNotificationCenter defaultCenter] postNotificationName:kEndPositionNotification object:[NSValue valueWithCGRect:btn.frame]]; //自动设置起始选择按钮
[self listClickLeftButton]; break;
}
}
}
} //自动设置起始选择按钮
- (void)listClickLeftButton{ if (!currentLeftBtn) {
[self tapBtn:_leftBtns[]];
return;
} NSUInteger tag = currentLeftBtn.tag;
if (tag < _leftBtns.count-) { //自动下移
[self tapBtn:_leftBtns[tag+]];
}
else{
[self tapBtn:_leftBtns[]]; //重新开始
}
} //绘制默认已经连线的选项,此处仅仅做成绩预览使用,不能再编辑
- (void)showLianXianResult{ for (UIButton *leftBtn in _leftBtns) {
leftBtn.layer.borderColor = [UIColor lightGrayColor].CGColor;
leftBtn.selected = leftBtn.userInteractionEnabled = NO;
} for (UIButton *rightBtn in _rightBtns) {
rightBtn.layer.borderColor = [UIColor lightGrayColor].CGColor;
rightBtn.selected = rightBtn.userInteractionEnabled = NO;
} if (self.lianxianModel.relationships.count == ) {
return;
} NSMutableArray *relationslineArray = [NSMutableArray array]; for (NSString *result in self.lianxianModel.relationships) { NSString *question = [[result componentsSeparatedByString:@"-"] firstObject];
NSString *option = [[result componentsSeparatedByString:@"-"] lastObject];
NSMutableArray *pointArray = [NSMutableArray array]; for (UIButton *leftBtn in _leftBtns) { if ([leftBtn.currentTitle isEqualToString:question]) {
CGPoint startPoint = CGPointMake(CGRectGetMaxX(leftBtn.frame), CGRectGetMidY(leftBtn.frame));
NSString *startPointString = NSStringFromCGPoint(startPoint);
[pointArray addObject:startPointString];
break;
}
} for (UIButton *rightBtn in _rightBtns) { if ([rightBtn.currentTitle isEqualToString:option]) {
CGPoint endPoint = CGPointMake(CGRectGetMinX(rightBtn.frame), CGRectGetMidY(rightBtn.frame));
NSString *endPointString = NSStringFromCGPoint(endPoint);
[pointArray addObject:endPointString];
break;
}
} [relationslineArray addObject:pointArray];
} if (relationslineArray.count > ) {
[[NSNotificationCenter defaultCenter] postNotificationName:kFreshDrawLineNotification object:relationslineArray];
}
} //重置初始状态
- (void)restStatus:(NSNotification *)notification{ for (UIButton *leftBtn in _leftBtns) {
leftBtn.selected = NO;
leftBtn.layer.borderColor = [UIColor lightGrayColor].CGColor;
[self tapBtn:_leftBtns[]]; //重新开始
}
} @end
(6)连线容器
LianXianContainerView.h
//
// LianXianContainerView.h
// LianxianDemo
//
// Created by 夏远全 on 2018/2/8.
// Copyright © 2018年 beijing. All rights reserved.
// #import <UIKit/UIKit.h>
#import "LianXianComponentsView.h"
#import "LianxianDrawView.h" @interface LianXianContainerView : UIView
@property (nonatomic, strong) LianXianComponentsView *componentsView;
@property (nonatomic, strong) LianxianDrawView *lianXianView;
@end
LianXianContainerView.m
//
// LianXianContainerView.m
// LianxianDemo
//
// Created by 夏远全 on 2018/2/8.
// Copyright © 2018年 beijing. All rights reserved.
// #import "LianXianContainerView.h"
#import "LianXianComponentsView.h"
#import "LianxianDrawView.h"
#import "LianXianModel.h" @implementation LianXianContainerView - (id)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
[self setup];
}
return self;
} - (void)setup{ self.lianXianView = [[LianxianDrawView alloc]initWithFrame:self.bounds];
self.componentsView = [[LianXianComponentsView alloc] initWithFrame:self.bounds]; [self addSubview:self.lianXianView];
[self addSubview:self.componentsView];
} @end
(7)显示连线
//
// ViewController.m
// LianxianDemo
//
// Created by tianjing on 15/3/31.
// Copyright © 2015年 tianjing. All rights reserved.
// #import "ViewController.h" #import "LianXianContainerView.h"
#import "LianXianFrameUitity.h"
#import "LianXianModel.h"
#import "LianXianHeader.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad]; UIButton *clearBtn = [[UIButton alloc] initWithFrame:CGRectMake(, , , )];
clearBtn.backgroundColor = [UIColor greenColor];
[clearBtn setTitle:@"重置" forState:UIControlStateNormal];
[clearBtn setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
[clearBtn addTarget:self action:@selector(clear:) forControlEvents:UIControlEventTouchUpInside]; //创建模型
LianXianModel *lianxianModel = [[LianXianModel alloc] init];
lianxianModel.questions = @[@"天",@"好",@"人"]; /// 左边选项
lianxianModel.options = @[@"夏",@"世",@"锋"]; /// 右边选项
//lianxianModel.relationships = @[@"天-世",@"好-夏",@"人-锋"]; /// 连线关系,如果不为空,就只显示,不能编辑
//clearBtn.hidden = (lianxianModel.relationships.count>0); //连线视图
CGRect frame = [LianXianFrameUitity calculateSizeWithModel:lianxianModel];
LianXianContainerView *containerView = [[LianXianContainerView alloc] initWithFrame:frame];
containerView.center = self.view.center;
containerView.componentsView.lianxianModel = lianxianModel; [self.view addSubview:containerView];
[self.view addSubview:clearBtn];
} - (void)clear:(UIButton *)sender{
[[NSNotificationCenter defaultCenter] postNotificationName:kClearAllLineNotification object:nil];
} @end
四、效果
提示:
左边按钮每次只有一个处于可连状态,而且每一次连接完会循环自动下移。
右边所有按钮始终处于可连状态。
同一个按钮再一次连接新的连线后,之前旧的跟其相关的连线都会被取消。
五、采坑
如果练习题的界面是放在cell中的,因为复用的问题,在发送起点和终点的通知时,要对通知做唯一标识处理。
如果不这么做,可能会出现的bug是:上一道做过的连线题的连线会出现在下一道还没有做过的连线题上。
iOS:练习题中如何用技术去实现一个连线题的更多相关文章
- linux中如何用root去修改其他用户的密码
linux中如何用root去修改其他用户的密码 昨天linux实验课,我有很多自己想摸索的东西.今天周五,本是下午一二节是编译的实验,可强烈的欲望让我今早就来实验室了,摸索吧,碰到了这个问题.... ...
- iOS开发中,如何恢复到某一个版本(Cornerstone)
Mac上的svn代码管理工具:Cornerstone 如何付恢复某个版本 第一:定位到你的工程,右上角边栏“Working Copy” ---->"Revert" 第二:选择 ...
- 在MacOS和iOS系统中使用OpenCV
在MacOS和iOS系统中使用OpenCV 前言 OpenCV 是一个开源的跨平台计算机视觉库,实现了图像处理和计算机视觉方面的很多通用算法. 最近试着在 MacOS 和 iOS 上使用 OpenCV ...
- iOS开发中获取视图在屏幕上显示的位置
在iOS开发中,我们会经常遇到一个问题,例如,点击一个按钮,弹出一个遮罩层,上面显示一个弹框,弹框显示的位置在按钮附近.如果这个按钮的位置相对于屏幕边缘的距离是固定的,那就容易了,可以直接写死位置.可 ...
- IOS开发中UITableView(表视图)的滚动优化及自定义Cell
IOS开发中UITableView(表视图)的滚动优化及自定义Cell IOS 开发中UITableView是非常常用的一个控件,我们平时在手机上看到的联系人列表,微信好友列表等都是通过UITable ...
- OS X 和iOS 中的多线程技术(上)
OS X 和iOS 中的多线程技术(上) 本文梳理了OS X 和iOS 系统中提供的多线程技术.并且对这些技术的使用给出了一些实用的建议. 多线程的目的:通过并发执行提高 CPU 的使用效率,进而提供 ...
- OS X 和iOS 中的多线程技术(下)
OS X 和iOS 中的多线程技术(下) 上篇文章中介绍了 pthread 和 NSThread 两种多线程的方式,本文将继续介绍 GCD 和 NSOperation 这两种方式.. 1.GCD 1. ...
- iOS中 Tagged Pointer 技术
前言: 从64位开始,iOS引入了Tagged Pointer技术,用于优化NSNumber.NSDate.NSString等小对象的存储. Tagged Pointer主要为了解决两个问题: 内 ...
- 多线程技术在iOS开发中的使用
进程和线程 要使用多线程,首先需要理解进程和线程这2个概念.这里我简单的说一下. 所谓进程对应的是一个应用程序,负责开辟内存空间供应用程序使用,但是进程不能执行任务(指令).一个进程至少包含一条线程, ...
随机推荐
- python词云
词云图 from os import path from PIL import Image import numpy as np import matplotlib.pyplot as plt fro ...
- 大数据-kafka
1Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据. 作用:1发布和订阅消息流,这个功能类似于消息队列,这也是kafka归类为消息队列框架的原因 2以容错 ...
- 扩展中国剩余定理 (exCRT) 的证明与练习
原文链接https://www.cnblogs.com/zhouzhendong/p/exCRT.html 扩展中国剩余定理 (exCRT) 的证明与练习 问题模型 给定同余方程组 $$\begin{ ...
- liunx系统虚拟机下安装tomcat9以及访问tomcat案例
在liunx系统虚拟机下安装tomcat9 首先下载好压缩包 liunx系统环境的安装包 将其解压到虚拟机自己创建的目录下 解压命令 tar -zxvf 文件名 解压好如图所示 然后修改配置文 ...
- mysql的基础增删改查(一)
修改,操作表:1.建表:create table MyClass(id int(4) not null primary key auto_increment,name char(20) not nul ...
- 1e9个兵临城下
https://ac.nowcoder.com/acm/contest/321#question 代码写得蛮丑的..真的很丑 像是高中教的veen图,并涉及到容斥原理. #include<cst ...
- Service工作原理
--摘自<android插件化开发指南> 一.在新进程启动Service 第一步:APP向AMS发送一个启动Service的消息 通过AMN/AMP把要启动的Service信息发送给AMS ...
- 从小白到区块链工程师:第一阶段:Go语言的HelloWorld初始(2)
四.写下第一段Go语言代码“Hello World” 小建议:就是文件夹路径或者文件名称不要出现中文,可能会导致一些不必要的麻烦(编译失败) 在sublime中,我们在src文件夹上面,单击右键“Ne ...
- spark实时计算性能优化
1. 计算提供两种模式,一种是jar包本地计算.一种是JSF服务. 2. 第一步是引入spark,因与netty.JDQ均有冲突,解决netty冲突后,隔离计算为单独服务.已在线上,因storm也 ...
- VC6.0学习C语言入门SDK
度网盘链接 VC6.0 密码:t6bd VS2010 密码:3of2 C语言入门教程 在线视频地址(PS此链接摘抄至博主lellansin) Acfun.tv:http://www.acfun. ...